<!DOCTYPE HTML>
<html lang="zh-CN">


<head>
    <meta charset="utf-8">
    <meta name="keywords" content="MySql语法整理, 大虫のBlog">
    <meta name="description" content="电子科技大学 | 信软学院 | 软件工程">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <meta name="renderer" content="webkit|ie-stand|ie-comp">
    <meta name="mobile-web-app-capable" content="yes">
    <meta name="format-detection" content="telephone=no">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
    <!-- Global site tag (gtag.js) - Google Analytics -->


    <title>MySql语法整理 | 大虫のBlog</title>
    <link rel="icon" type="image/png" href="/favicon.png">

    <link rel="stylesheet" type="text/css" href="/libs/awesome/css/all.css">
    <link rel="stylesheet" type="text/css" href="/libs/materialize/materialize.min.css">
    <link rel="stylesheet" type="text/css" href="/libs/aos/aos.css">
    <link rel="stylesheet" type="text/css" href="/libs/animate/animate.min.css">
    <link rel="stylesheet" type="text/css" href="/libs/lightGallery/css/lightgallery.min.css">
    <link rel="stylesheet" type="text/css" href="/css/matery.css">
    <link rel="stylesheet" type="text/css" href="/css/my.css">

    <script src="/libs/jquery/jquery.min.js"></script>

<meta name="generator" content="Hexo 6.2.0"></head>




<body>
    <header class="navbar-fixed">
    <nav id="headNav" class="bg-color nav-transparent">
        <div id="navContainer" class="nav-wrapper container">
            <div class="brand-logo">
                <a href="/" class="waves-effect waves-light">
                    
                    <img src="/medias/logo.png" class="logo-img" alt="LOGO">
                    
                    <span class="logo-span">大虫のBlog</span>
                </a>
            </div>
            

<a href="#" data-target="mobile-nav" class="sidenav-trigger button-collapse"><i class="fas fa-bars"></i></a>
<ul class="right nav-menu">
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/" class="waves-effect waves-light">
      
      <i class="fas fa-home" style="zoom: 0.6;"></i>
      
      <span>首页</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/tags" class="waves-effect waves-light">
      
      <i class="fas fa-tags" style="zoom: 0.6;"></i>
      
      <span>标签</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/categories" class="waves-effect waves-light">
      
      <i class="fas fa-bookmark" style="zoom: 0.6;"></i>
      
      <span>分类</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/archives" class="waves-effect waves-light">
      
      <i class="fas fa-archive" style="zoom: 0.6;"></i>
      
      <span>归档</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/about" class="waves-effect waves-light">
      
      <i class="fas fa-user-circle" style="zoom: 0.6;"></i>
      
      <span>关于</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/contact" class="waves-effect waves-light">
      
      <i class="fas fa-comments" style="zoom: 0.6;"></i>
      
      <span>留言板</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/friends" class="waves-effect waves-light">
      
      <i class="fas fa-address-book" style="zoom: 0.6;"></i>
      
      <span>友情链接</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="" class="waves-effect waves-light">

      
      <i class="fa fa-list" style="zoom: 0.6;"></i>
      
      <span>其他</span>
      <i class="fas fa-chevron-down" aria-hidden="true" style="zoom: 0.6;"></i>
    </a>
    <ul class="sub-nav menus_item_child ">
      
      <li>
        <a target="_blank" rel="noopener" href="https://console.leancloud.cn">
          
          <i class="fa-solid fa-link" style="margin-top: -20px; zoom: 0.6;"></i>
          
          <span>LeanCloud 应用</span>
        </a>
      </li>
      
      <li>
        <a target="_blank" rel="noopener" href="https://www.tidio.com/panel">
          
          <i class="fa-solid fa-link" style="margin-top: -20px; zoom: 0.6;"></i>
          
          <span>TIDIO 聊天系统</span>
        </a>
      </li>
      
      <li>
        <a target="_blank" rel="noopener" href="https://www.coderutil.com">
          
          <i class="fa-solid fa-link" style="margin-top: -20px; zoom: 0.6;"></i>
          
          <span>CoderUtil 工具</span>
        </a>
      </li>
      
    </ul>
    
  </li>
  
  <li>
    <a href="#searchModal" class="modal-trigger waves-effect waves-light">
      <i id="searchIcon" class="fas fa-search" title="搜索" style="zoom: 0.85;"></i>
    </a>
  </li>
</ul>


<div id="mobile-nav" class="side-nav sidenav">

    <div class="mobile-head bg-color">
        
        <img src="/medias/logo.png" class="logo-img circle responsive-img">
        
        <div class="logo-name">大虫のBlog</div>
        <div class="logo-desc">
            
            电子科技大学 | 信软学院 | 软件工程
            
        </div>
    </div>

    

    <ul class="menu-list mobile-menu-list">
        
        <li class="m-nav-item">
	  
		<a href="/" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-home"></i>
			
			首页
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/tags" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-tags"></i>
			
			标签
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/categories" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-bookmark"></i>
			
			分类
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/archives" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-archive"></i>
			
			归档
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/about" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-user-circle"></i>
			
			关于
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/contact" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-comments"></i>
			
			留言板
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/friends" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-address-book"></i>
			
			友情链接
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="javascript:;">
			
				<i class="fa-fw fa fa-list"></i>
			
			其他
			<span class="m-icon"><i class="fas fa-chevron-right"></i></span>
		</a>
            <ul  style="background:  ;" >
              
                <li>

                  <a target="_blank" rel="noopener" href="https://console.leancloud.cn " style="margin-left:75px">
				  
				   <i class="fa fa-solid fa-link" style="position: absolute;left:50px" ></i>
			      
		          <span>LeanCloud 应用</span>
                  </a>
                </li>
              
                <li>

                  <a target="_blank" rel="noopener" href="https://www.tidio.com/panel " style="margin-left:75px">
				  
				   <i class="fa fa-solid fa-link" style="position: absolute;left:50px" ></i>
			      
		          <span>TIDIO 聊天系统</span>
                  </a>
                </li>
              
                <li>

                  <a target="_blank" rel="noopener" href="https://www.coderutil.com " style="margin-left:75px">
				  
				   <i class="fa fa-solid fa-link" style="position: absolute;left:50px" ></i>
			      
		          <span>CoderUtil 工具</span>
                  </a>
                </li>
              
            </ul>
          
        </li>
        
        
        <li><div class="divider"></div></li>
        <li>
            <a href="https://gitee.com/yczlab" class="waves-effect waves-light" target="_blank">
                <i class="fab fa-github-square fa-fw"></i>Fork Me
            </a>
        </li>
        
    </ul>
</div>


        </div>

        
            <style>
    .nav-transparent .github-corner {
        display: none !important;
    }

    .github-corner {
        position: absolute;
        z-index: 10;
        top: 0;
        right: 0;
        border: 0;
        transform: scale(1.1);
    }

    .github-corner svg {
        color: #0f9d58;
        fill: #fff;
        height: 64px;
        width: 64px;
    }

    .github-corner:hover .octo-arm {
        animation: a 0.56s ease-in-out;
    }

    .github-corner .octo-arm {
        animation: none;
    }

    @keyframes a {
        0%,
        to {
            transform: rotate(0);
        }
        20%,
        60% {
            transform: rotate(-25deg);
        }
        40%,
        80% {
            transform: rotate(10deg);
        }
    }
</style>

<a href="https://gitee.com/yczlab" class="github-corner tooltipped hide-on-med-and-down" target="_blank"
   data-tooltip="Fork Me" data-position="left" data-delay="50">
    <svg viewBox="0 0 250 250" aria-hidden="true">
        <path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path>
        <path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2"
              fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path>
        <path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z"
              fill="currentColor" class="octo-body"></path>
    </svg>
</a>
        
    </nav>

</header>

    



<div class="bg-cover pd-header post-cover" style="background-image: url('/medias/featureimages/20.jpg')">
    <div class="container" style="right: 0px;left: 0px;">
        <div class="row">
            <div class="col s12 m12 l12">
                <div class="brand">
                    <h1 class="description center-align post-title">MySql语法整理</h1>
                </div>
            </div>
        </div>
    </div>
</div>




<main class="post-container content">

    
    <link rel="stylesheet" href="/libs/tocbot/tocbot.css">
<style>
    #articleContent h1::before,
    #articleContent h2::before,
    #articleContent h3::before,
    #articleContent h4::before,
    #articleContent h5::before,
    #articleContent h6::before {
        display: block;
        content: " ";
        height: 100px;
        margin-top: -100px;
        visibility: hidden;
    }

    #articleContent :focus {
        outline: none;
    }

    .toc-fixed {
        position: fixed;
        top: 64px;
    }

    .toc-widget {
        width: 345px;
        padding-left: 20px;
    }

    .toc-widget .toc-title {
        padding: 35px 0 15px 17px;
        font-size: 1.5rem;
        font-weight: bold;
        line-height: 1.5rem;
    }

    .toc-widget ol {
        padding: 0;
        list-style: none;
    }

    #toc-content {
        padding-bottom: 30px;
        overflow: auto;
    }

    #toc-content ol {
        padding-left: 10px;
    }

    #toc-content ol li {
        padding-left: 10px;
    }

    #toc-content .toc-link:hover {
        color: #42b983;
        font-weight: 700;
        text-decoration: underline;
    }

    #toc-content .toc-link::before {
        background-color: transparent;
        max-height: 25px;

        position: absolute;
        right: 23.5vw;
        display: block;
    }

    #toc-content .is-active-link {
        color: #42b983;
    }

    #floating-toc-btn {
        position: fixed;
        right: 15px;
        bottom: 76px;
        padding-top: 15px;
        margin-bottom: 0;
        z-index: 998;
    }

    #floating-toc-btn .btn-floating {
        width: 48px;
        height: 48px;
    }

    #floating-toc-btn .btn-floating i {
        line-height: 48px;
        font-size: 1.4rem;
    }
</style>
<div class="row">
    <div id="main-content" class="col s12 m12 l9">
        <!-- 文章内容详情 -->
<div id="artDetail">
    <div class="card">
        <div class="card-content article-info">
            <div class="row tag-cate">
                <div class="col s7">
                    
                    <div class="article-tag">
                        
                            <a href="/tags/MySql/">
                                <span class="chip bg-color">MySql</span>
                            </a>
                        
                    </div>
                    
                </div>
                <div class="col s5 right-align">
                    
                    <div class="post-cate">
                        <i class="fas fa-bookmark fa-fw icon-category"></i>
                        
                            <a href="/categories/MySql/" class="post-category">
                                MySql
                            </a>
                        
                    </div>
                    
                </div>
            </div>

            <div class="post-info">
                
                <div class="post-date info-break-policy">
                    <i class="far fa-calendar-minus fa-fw"></i>发布日期:&nbsp;&nbsp;
                    2021-10-09
                </div>
                

                
                <div class="post-date info-break-policy">
                    <i class="far fa-calendar-check fa-fw"></i>更新日期:&nbsp;&nbsp;
                    2022-08-07
                </div>
                

                
                <div class="info-break-policy">
                    <i class="far fa-file-word fa-fw"></i>文章字数:&nbsp;&nbsp;
                    23.6k
                </div>
                

                
                <div class="info-break-policy">
                    <i class="far fa-clock fa-fw"></i>阅读时长:&nbsp;&nbsp;
                    100 分
                </div>
                

                
                    <div id="busuanzi_container_page_pv" class="info-break-policy">
                        <i class="far fa-eye fa-fw"></i>阅读次数:&nbsp;&nbsp;
                        <span id="busuanzi_value_page_pv"></span>
                    </div>
				
            </div>
        </div>
        <hr class="clearfix">

        
        <!-- 是否加载使用自带的 prismjs. -->
        <link rel="stylesheet" href="/libs/prism/prism.css">
        

        

        <div class="card-content article-card-content">
            <div id="articleContent">
                <p>  </p>
<h2 id="引言："><a href="#引言：" class="headerlink" title="引言："></a>引言：</h2><blockquote>
<p>这里只是对一些简单的MySql语法做一些整理，增删改查，建表删表，存储过程等。</p>
</blockquote>
<h3 id="一、MySql常见命令"><a href="#一、MySql常见命令" class="headerlink" title="一、MySql常见命令"></a>一、MySql常见命令</h3><p><strong>1、登录</strong></p>
<blockquote>
<p><code>mysql [-h主机名 -P端口号] -u用户名 -p密码</code></p>
</blockquote>
<p><strong>2、退出</strong></p>
<blockquote>
<p><code>exit 或者 ctlr+c</code></p>
</blockquote>
<p><strong>3、查看当前所有的数据库</strong></p>
<blockquote>
<p><code>show databases;</code></p>
</blockquote>
<p><strong>4、打开指定的数据库</strong></p>
<blockquote>
<p><code>use 库名;</code></p>
</blockquote>
<p><strong>5、查看当前库的所有表</strong></p>
<blockquote>
<p><code>show tables;</code></p>
</blockquote>
<p><strong>6、查看其它库的所有表</strong></p>
<blockquote>
<p><code>show tables from 库名;</code></p>
</blockquote>
<p><strong>7、创建表</strong></p>
<blockquote>
<p><font color="#e96900">create table 表名(<br>  列明 列类型,<br>  列明 列类型,<br>  ……<br>);</font></p>
</blockquote>
<p><strong>8、查看表的结构</strong></p>
<blockquote>
<p><code>desc 表名;</code></p>
</blockquote>
<p><strong>9、查看MySql服务器版本</strong></p>
<blockquote>
<ul>
<li><code>select version();</code>（适合于已登录到mysql服务端）</li>
<li><code>mysql --version</code>（适合于没有登录到mysql服务端）</li>
<li><code>mysql --V</code>（适合于没有登录到mysql服务端）</li>
</ul>
</blockquote>
<hr>
<h3 id="二、MySql的语法规范"><a href="#二、MySql的语法规范" class="headerlink" title="二、MySql的语法规范"></a>二、MySql的语法规范</h3><p>1、不区分大小写，但是建议关键字大写，表名、列名小写；<br>2、每条命令最好用分号结尾；<br>3、每条命令根据需要，可以进行缩进或换行；<br>4、注释</p>
<blockquote>
<p>单行注释：<code>#注释文字</code><br>单行注释：<code>-- 注释文字</code><br>多行注释：<code>/* 注释文字 */</code></p>
</blockquote>
<hr>
<h3 id="注、本教程中用到的数据库脚本"><a href="#注、本教程中用到的数据库脚本" class="headerlink" title="注、本教程中用到的数据库脚本"></a>注、本教程中用到的数据库脚本</h3><p>员工信息数据库，<a href="b6041c1e/myemployees.sql">sql脚本下载</a></p>
<blockquote>
<p><img src="/posts/b6041c1e/myemployees.png"></p>
</blockquote>
<p>男生女神数据库，<a href="b6041c1e/girls.sql">sql脚本下载</a></p>
<blockquote>
<p><img src="/posts/b6041c1e/girls.png"></p>
</blockquote>
<hr>
<h3 id="三、DQL-数据查询语言"><a href="#三、DQL-数据查询语言" class="headerlink" title="三、DQL 数据查询语言"></a>三、DQL 数据查询语言</h3><p>  <strong>Data Query Language</strong></p>
<h4 id="A、基础查询"><a href="#A、基础查询" class="headerlink" title="A、基础查询"></a>A、基础查询</h4><p><strong>1、语法</strong></p>
<blockquote>
<p><font color="#e96900">select 查询列表<br>from 表名</font></p>
<blockquote>
<p>查询列表可以是：表中的字段、常量、表达式、函数，可以是它们的组合<br>查询的结果是一个虚拟的表格，并不是真实存在的</p>
</blockquote>
</blockquote>
<p><strong>2、查询表中单个或多个字段</strong></p>
<blockquote>
<ul>
<li><code>select last_name from employees;</code></li>
<li><code>select last_name, salary, email from employees;</code></li>
</ul>
</blockquote>
<p><strong>3、查询表中的所有字段</strong></p>
<blockquote>
<p><code>select * from employees;</code></p>
<blockquote>
<p>这种方式的弊端就是列名的顺序就是原始表中的列名顺序</p>
</blockquote>
</blockquote>
<p><strong>4、查询常量值、表达式、函数</strong></p>
<blockquote>
<p>查询<strong>字符型</strong>或<strong>日期型</strong>的常量必须用单引号或双引号引起来，数值型不需要</p>
<ul>
<li><p><code>select 常量值;</code></p>
<blockquote>
<ul>
<li><code>select 100;</code></li>
<li><code>select &#39;jerry&#39;;</code></li>
<li><code>select &quot;Tom&quot;;</code></li>
</ul>
</blockquote>
</li>
<li><p><code>select 表达式;</code></p>
<blockquote>
<ul>
<li><code>select 100*98;</code></li>
<li><code>select 100%99;</code></li>
</ul>
</blockquote>
</li>
<li><p><code>select 函数(实参列表);</code></p>
<blockquote>
<ul>
<li><code>select version();</code></li>
<li><code>select database();</code></li>
</ul>
</blockquote>
</li>
</ul>
</blockquote>
<p><strong>5、查询时为字段起别名</strong></p>
<blockquote>
<p>方式一（使用关键字AS）：</p>
<ul>
<li><code>select 100%98 as 结果;</code></li>
<li><code>select last_name as 姓, first_name as 名 from employees;</code></li>
</ul>
<p>方式二（直接使用空格）：</p>
<ul>
<li><code>select last_name 姓, first_name 名 from employees;</code></li>
</ul>
<p>起别名好处：</p>
<ul>
<li>便于理解</li>
<li>在某些关联查询中如果字段有重名的情况，使用别名可以很好地区分开来</li>
</ul>
<p>案列：查询salary，显示结果为 out put</p>
<ul>
<li><code>select salary as out put from employees;</code> 直接报错</li>
<li><code>select salary as &#39;out put&#39; from employees;</code> 成功执行</li>
<li><code>select salary as &quot;out put&quot; from employees;</code> 成功执行</li>
<li>当别名中存在特殊符号，比如空格#号时，要在别名上加上单引号或者双引号</li>
</ul>
</blockquote>
<p><strong>6、查询去重</strong></p>
<blockquote>
<p>查询员工表中涉及到的所有部门编号<br><code>select distinct department_id from employees;</code></p>
</blockquote>
<p><strong>7、加号 “+” 的使用注意</strong></p>
<blockquote>
<p>查询员工的姓和名，并连接成一个字段显示为 姓名<br><code>select last_name+first_name as 姓名 from employees;</code> 结果全是0，和预想的完全不一样</p>
<blockquote>
<ul>
<li>java中的 +号 可以作为运算符，也可以作为字符串的连接符，当左右两个操作数都是数值型时其作为运算符，而只要有一个操作数为字符串其就作为连接符。</li>
<li>mysql中的 +号 只能作为运算符来使用。当左右两边的操作数不能装换为数值时，就默认转换为0</li>
</ul>
</blockquote>
<ul>
<li><code>select 100+90;</code> 两个操作数都为数值型，则做加法运算</li>
<li><code>select &#39;123&#39;+90;</code> 其中一方为字符型，则试图将字符型数值转换成数值型，再做加法运算</li>
<li><code>select &#39;123&#39;+&#39;456&#39;;</code> 两个操作数都为字符型，则一样试图做转换，再做加法运算</li>
<li><code>select &#39;123&#39;+&#39;abc&#39;;</code> 若字符型不能转换成数值型，则默认转换成0</li>
<li><code>select 123+null;</code> 只要其中一方为null，则结果一定为null</li>
</ul>
</blockquote>
<p><strong>8、使用 CONCAT 实现连接</strong></p>
<blockquote>
<p><code>SELECT CONCAT(字段1, 字段2, 字段3, ......);</code><br>案例1：查询员工的姓和名，并连接成一个字段显示为 姓名<br><code>select concat(last_name, first_name) as 姓名 from employees;</code><br>CONCAT还可以连接多个字段，也就是说该函数具有可变数量个参数<br><code>select CONCAT(&#39;a&#39;, &#39;b&#39;, &#39;c&#39;, last_name) as 结果 from employees;</code><br>特殊案例：null 拼接<br><code>select CONCAT(null, last_name) as 结果 from employees;</code> 结果全为NULL，又和预想的不一样。</p>
<blockquote>
<ul>
<li>null和任何其他字符拼接，结果都为null</li>
<li>可以使用 IFNULL(expr1, expr2) 做一下判断，判断字段是否为null，并返回指定的表达式值。其中expr1表示想要判断的字段，expr2表示如果expr1为null，该函数将返回expr2。如果expr1不为null，则返回expr1本身。</li>
</ul>
</blockquote>
<p> <code>select commission_pct, ifnull(commission_pct, &quot;0.0&quot;) as 奖金率 from employees;</code></p>
</blockquote>
<p><strong>9、IFNULL(expr1, expr2)函数</strong><br>  判断某字段或表达式是否为null，如果为null，则返回指定的表达式或字段值；否则返回原本的值</p>
<blockquote>
<p><code>select commission_pct, ifnull(commission_pct,0) as 奖金率 from employees;</code></p>
</blockquote>
<p><strong>10、ISNULL(expr)函数</strong><br>  判断某字段或表达式是否为null，如果为null，则返回1；否则返回0</p>
<blockquote>
<p><code>select commission_pct, isnull(commission_pct) from employees;</code></p>
</blockquote>
<h4 id="B、条件查询"><a href="#B、条件查询" class="headerlink" title="B、条件查询"></a>B、条件查询</h4><p><strong>1、语法</strong></p>
<blockquote>
<p><font color="#e96900">select 查询列表<br>from 表名<br>where 筛选条件;</font></p>
<blockquote>
<p>“筛选条件”分类：</p>
<ul>
<li>按条件表达式筛选<br>简单条件运算符： <strong>“&gt;”</strong>  <strong>“&gt;&#x3D;”</strong>  <strong>“&lt;”</strong>  <strong>“&lt;&#x3D;”</strong> <strong>“&#x3D;”</strong>  <strong>“!&#x3D;”</strong>  <strong>“&lt;&gt;”</strong>  <strong>“&lt;&#x3D;&gt;”</strong></li>
<li>按逻辑表达式筛选<br>逻辑运算符(作用就是用来连接条件表达式)： <strong>“&amp;&amp;”</strong>  <strong>“||”</strong>  <strong>“!”</strong><br>逻辑运算符(推荐使用)： <strong>“and”</strong>  <strong>“or”</strong>  <strong>“not”</strong></li>
<li>模糊查询<br>特殊条件运算符： <strong>“like”</strong>  <strong>“between and”</strong>  <strong>“in”</strong>  <strong>“is null”</strong>  <strong>“is not null”</strong></li>
</ul>
</blockquote>
</blockquote>
<p><strong>2、按条件表达式筛选</strong></p>
<blockquote>
<p>案例1：查询工资&gt;12000的员工信息</p>
<blockquote>
<p><code>select * from employees where salary&gt;12000;</code></p>
</blockquote>
<p>案例2：查询部门编号不等于90号的员工名和部门编号</p>
<blockquote>
<p><font color="#e96900">select concat(last_name, first_name) as 姓名<br>from employees<br>where department_id&lt;&gt;90;</font></p>
</blockquote>
</blockquote>
<p><strong>2、逻辑表达式筛选</strong></p>
<blockquote>
<p>案例1：查询工资在10000到20000之间的员工名、工资以及奖金</p>
<blockquote>
<p><font color="#e96900">select first_name,salary,commission_pct<br>from employees<br>where salary&gt;&#x3D;10000 and salary&lt;&#x3D;20000;</font></p>
</blockquote>
<p>案例2：查询部门编号不是在90到110之间，或者工资高于15000的员工信息</p>
<blockquote>
<p><font color="#e96900">select *<br>from employees<br>where department_id&lt;90 or department_id&gt;110 or salary&gt;15000;</font></p>
<hr>
<p><font color="#e96900">select *<br>from employees<br>where department_id not between 90 and 110 or salary&gt;15000;</font></p>
<hr>
<p><font color="#e96900">select *<br>from employees<br>where NOT(department_id&gt;&#x3D;90 and department_id&lt;&#x3D;110) or salary&gt;15000</font></p>
</blockquote>
</blockquote>
<p><strong>3、模糊查询</strong></p>
<ul>
<li><p><strong>3.1 “like”</strong></p>
<blockquote>
<p>一般和通配符搭配使用，<strong>注意：</strong>当查询字段的值为NULL时，不能做出有效的判断</p>
<blockquote>
<p><strong>“%”</strong> 匹配任意多个字符（包含0个字符）<br><strong>“_”</strong> 匹配任意单个字符<br><strong>“\”</strong> 表示转义字符，当要匹配特殊字符时，比如就要匹配“%”或者“_”时使用</p>
</blockquote>
<p>案例1：查询员工名中包含字符’a’的员工信息</p>
<blockquote>
<p><font color="#e96900">select *<br>from employees<br>where last_name like &#39;%a%&#39;;</font></p>
</blockquote>
<p>案例2：查询员工名中第三个字符为’n’，第五个字符为’l’的员工名和工资</p>
<blockquote>
<p><font color="#e96900">select last_name,salary<br>from employees<br>where last_name like &#39;__n_l%&#39;;</font></p>
</blockquote>
<p>案例3：查询员工名中第二个字符为’_’的员工名</p>
<blockquote>
<p><code>select last_name from employees where last_name like &#39;_\_%&#39;;</code></p>
<blockquote>
<p>“\“表示转义字符，当然你也可以使用“ESCAPE”随意指定一个字符作为转义字符，比如指定“$”<br><code>select last_name from employees where last_name like &#39;_$_%&#39; ESCAPE &#39;$&#39;;</code></p>
</blockquote>
</blockquote>
<p>案例4：查询员工的薪水中万位数字为’2’的员工名和薪水</p>
<blockquote>
<p><code>select last_name, salary from employees where salary like &#39;%2____.%&#39;;</code><br>（就是为了说明 <strong>like</strong> 不仅可以用来模糊字符型数据，甚至可以是数模糊数值型数据）</p>
</blockquote>
</blockquote>
</li>
<li><p><strong>3.2 “between and”</strong></p>
<blockquote>
<p>案例1：查询员工编号在100到120之间的员工信息</p>
<blockquote>
<ul>
<li><font color="#e96900">select * from employees where department_id&gt;&#x3D;100 and department_id&lt;&#x3D;120;</font></li>
<li><font color="#e96900">select * from employees where department_id between 100 and 120;</font><br>使用“between and”可以提高语句的简洁度，同时也可以看出“between and”是包括左右端点的，且左右端点值不能交换顺序，写成“between 120 and 100”就啥也查不出来。</li>
</ul>
</blockquote>
</blockquote>
</li>
<li><p><strong>3.3 “in”</strong></p>
<blockquote>
<p>判断某字段的值是否属于 in 列表中的某一项<br>案例1：查询员工的工种标号是 IT_PROG、AD_VP、AD_PRES 中的一种的员工编号</p>
<blockquote>
<ul>
<li><font color="#e96900">select job_id from employees where job_id&#x3D;&quot;IT_PROG&quot; or job_id&#x3D;&#39;AD_VP&#39; or job_id&#x3D;&#39;AD_PRES&#39;;</font></li>
<li><font color="#e96900">select job_id from employees where job_id in (&#39;IT_PROG&#39;, &quot;AD_VP&quot;, &#39;AD_PRES&#39;);</font><br>同样使用“in”可以提高语句的简洁度，in列表中的值类型必须一致或兼容，in列表中的值无法使用通配符。</li>
</ul>
</blockquote>
</blockquote>
</li>
<li><p><strong>3.4 “is null &#x2F; is not null”</strong></p>
<blockquote>
<p>案例1：查询没有奖金的员工名和奖金率</p>
<blockquote>
<ul>
<li><font color="#e96900">select last_name,commission_pct from employees where commission_pct&#x3D;NULL;</font> 结果和预想的不一样，因为“&#x3D;”不能用来判断null。</li>
<li><font color="#e96900">select last_name,commission_pct from employees where commission_pct is null;</font> 正确执行。</li>
</ul>
</blockquote>
<p>案例2：查询有奖金的员工名和奖金率</p>
<blockquote>
<ul>
<li><font color="#e96900">select last_name,commission_pct from employees where commission_pct !&#x3D;null;</font> 同上，结果和预想的不一样，因为“!&#x3D;”不能用来判断null。</li>
<li><font color="#e96900">select last_name,commission_pct from employees where commission_pct is not null;</font> 正确执行。</li>
</ul>
</blockquote>
<p><strong>注意：</strong></p>
<blockquote>
<ul>
<li><strong>“&#x3D;”或“&lt;&gt;”不能用来判断 NULL 值</strong></li>
<li><strong>“is null”和“is not null”主要就是用来判断 NULL 值的</strong></li>
<li><strong>is 后面只能接null或则not null，不能接其他的，比如where salary is 12000 是错误的用法</strong></li>
</ul>
</blockquote>
</blockquote>
</li>
</ul>
<p><strong>4、安全的等于“&lt;&#x3D;&gt;”</strong><br>  <strong>“&lt;&#x3D;&gt;”可以用来判断null值，也可以用来判断普通类型的值。但是可读性很差，不常用。</strong></p>
<blockquote>
<p>案例1：查询没有奖金的员工名和奖金率</p>
<blockquote>
<p><font color="#e96900">select last_name, commission_pct<br>from employees<br>where commission_pct&lt;&#x3D;&gt;null;</font></p>
</blockquote>
<p>案例2：查询工资为12000的员工名和奖金率</p>
<blockquote>
<p><font color="#e96900">select last_name, commission_pct<br>from employees<br>where salary &lt;&#x3D;&gt;12000;</font></p>
</blockquote>
</blockquote>
<h4 id="C、排序查询"><a href="#C、排序查询" class="headerlink" title="C、排序查询"></a>C、排序查询</h4><p><strong>1、语法</strong></p>
<blockquote>
<p><font color="#e96900">select 查询列表<br>from 表名<br>[where 筛选条件]<br>order by 排序列表 [asc|desc]</font></p>
<blockquote>
<p>特点：</p>
<ul>
<li>asc代表的是升序，desc代表的是降序，如果不写，则默认是升序</li>
<li>order by 子句中可以支持单个字段、多个字段、表达式、函数、别名</li>
<li>order by 字句一般是放在查询语句的最后面，<strong>limit字句除外</strong></li>
<li>目前的执行顺序为：from –&gt; where –&gt; select –&gt; order</li>
</ul>
</blockquote>
</blockquote>
<p><strong>2、案例</strong></p>
<blockquote>
<p>案例1：查询员工信息，要求工资从高到低排序（或则从低到高）</p>
<ul>
<li><code>select * from employees order by salary DESC;</code> 降序</li>
<li><code>select * from employees order by salary ASC;</code> 升序（默认）</li>
</ul>
<p>案例2：查询部门编号大于等于90的员工信息，按入职时间的先后进行排序【添加筛选条件】</p>
<ul>
<li><code>select * from employees where department_id&gt;=90 order by hiredate ASC;</code></li>
<li><code>select * from employees where department_id&gt;=90 order bu hiredate DESC;</code></li>
</ul>
<p>案例3：按年薪的高低显示员工的信息和 年薪【按表达式排序】</p>
<ul>
<li><font color="#e96900">select <em>, salary</em>12*(1+ifnull(commission_pct,0))<br>from employees<br>order by salary<em>12</em>(1+ifnull(commission_pct,0)) desc;</font></li>
</ul>
<p>案例4：按年薪的高低显示员工的信息和 年薪【按表别名排序】</p>
<ul>
<li><font color="#e96900">select <em>, salary</em>12*(1+ifnull(commission_pct,0)) as year_salary<br>from employees<br>order by year_salary desc;</font></li>
</ul>
<p>案例5：按姓名的长度显示员工的姓名和工资【按函数排序】</p>
<ul>
<li><font color="#e96900">select LENGTH(last_name) 字节长度, last_name, salary<br>from employees<br>order by 字节长度 ASC;</font></li>
</ul>
<p>案例6：查询员工信息，要求先按工资排序（降序），再按员工编号排序（升序）【按多个字段排序】</p>
<ul>
<li><font color="#e96900">selecy last_name, salary, employee_id<br>from employees<br>order by salary desc, employee_id asc;</font></li>
</ul>
<p>案例7：查询员工的姓名、部门、年薪，按年薪降序，按姓名升序</p>
<ul>
<li><font color="#e96900">select last_name, department_id, salary<em>12</em>(1+ifnull(commission_pct,0)) year_salary<br>from employees<br>order by year_salary DESC, last_name ASC;</font></li>
</ul>
<p>案例8：选择工资不在8000到17000的员工的姓名和工资，按工资降序</p>
<ul>
<li><font color="#e96900">select last_name, salary<br>from employees<br>where not between 8000 and 17000<br>order by salary desc;</font></li>
</ul>
<p>案例9：查询邮箱中包含’e’的员工信息，并先按邮箱的字节数降序，再按部门号升序</p>
<ul>
<li><font color="#e96900">select *<br>from employees<br>where email like &#39;%e%&#39;<br>order by LENGTH(email) DESC, department_id ASC;</font></li>
</ul>
</blockquote>
<h4 id="D、常见函数"><a href="#D、常见函数" class="headerlink" title="D、常见函数"></a>D、常见函数</h4><p>  MySql中的函数类似于java中的方法，将一组逻辑语句封装在方法体中，对外暴露方法名。<strong>好处：①隐藏了实现细节 ②提高了代码的重用性</strong></p>
<p><strong>1、调用语法</strong></p>
<blockquote>
<p><font color="#e96900">select 函数名(实参列表) 【from 表名】;</font></p>
<blockquote>
<p>分类：</p>
<ul>
<li>单行函数：concat(str1, str2,…)、length(str)、ifnull(expr1, expr2)、isnull(expr)</li>
<li>分组函数：主要是做统计使用，又称为统计函数、聚合函数、主函数</li>
</ul>
<p>单行函数:</p>
<ul>
<li>字符函数</li>
<li>数学函数</li>
<li>日期函数</li>
<li>其他函数</li>
<li>流程控制函数</li>
</ul>
<p>分组函数：</p>
<ul>
<li>sum 求和</li>
<li>avg 平均值</li>
<li>max 最大值</li>
<li>min 最小值</li>
<li>count 计算个数</li>
</ul>
</blockquote>
</blockquote>
<p><strong>2、字符函数</strong></p>
<blockquote>
<p><strong>2.1、length(str)</strong> 获取参数值的字节个数</p>
<ul>
<li><code>select length(&#39;john&#39;);</code></li>
<li><code>select LENGTH(&quot;张三丰hahaha&quot;);</code> 跟字符集有关，utf8中汉字占三个字节，字母占一个字节</li>
</ul>
<p><strong>2.2、concat(str1, str2, …)</strong> 拼接字符串</p>
<ul>
<li><code>select concat(last_name, &#39;_&#39;, first_name) from employees;</code></li>
</ul>
<p><strong>2.3、upper(str) &#x2F; lower(str)</strong> 字符大小写转换</p>
<ul>
<li><code>select upper(&#39;john&#39;);</code></li>
<li><code>select lower(&#39;Tom&#39;);</code></li>
<li><code>select concat(upper(last_name), lower(first_name)) from employees;</code></li>
</ul>
<p><strong>2.4、substr &#x2F; substring</strong> 字符串截取。注意：以下的pos是从 1 开始，并非从 0 开始，也就是索引是从 1 开始的</p>
<ul>
<li><strong>substr(str, pos) &#x2F; substring(str, pos)</strong> 从指定索引处pos开始截取，一直到字符串末尾<ul>
<li><code>select substr(&#39;李莫愁爱上了陆展元&#39;, 7) as out_put;</code> 返回结果“陆展元”</li>
<li><code>select substr(&#39;李莫愁爱上了陆展元&#39;, -3) as out_put;</code> pos可以为负数，表示倒着数</li>
</ul>
</li>
<li><strong>substr(str, pos, len) &#x2F; substring(str, pos, len)</strong> 从指定索引处pos开始截取，截取固定字符长度len<ul>
<li><code>select substr(&#39;李莫愁爱上了陆展元&#39;, 1, 3) as out_put;</code> 返回结果“李莫愁”</li>
<li><code>select substr(&#39;李莫愁爱上了陆展元&#39;, -9, 3) as out_put;</code></li>
</ul>
</li>
<li><strong>substr(str FROM pos) &#x2F; substring(str FROM pos)</strong><ul>
<li><code>select substr(&#39;李莫愁爱上了陆展元&#39; FROM 7) as out_put;</code></li>
<li><code>select substr(&#39;李莫愁爱上了陆展元&#39; FROM -3) as out_put;</code></li>
</ul>
</li>
<li><strong>substr(str FROM pos FOR len) &#x2F; substring(str FROM pos For len)</strong><ul>
<li><code>select substr(&#39;李莫愁爱上了陆展元&#39; FROM 1 FOR 3) as out_put;</code></li>
<li><code>select substr(&#39;李莫愁爱上了陆展元&#39; FROM -9 FOR 3) as out_put;</code></li>
</ul>
</li>
<li>案例1：姓名中首字符大写，其他字符小写然后用’_’拼接，显示出来<ul>
<li><code>select CONCAT(upper(substr(last_name,1,1)), &#39;_&#39;, lower(substr(last_name,2))) as name from employees;</code></li>
</ul>
</li>
</ul>
<p><strong>2.5、instr(str, substr)</strong> 判断字符串中是否包含指定子串，返回 1 表示包含，0 表示不包含</p>
<ul>
<li><code>select instr(&#39;杨不悔爱上了殷六侠&#39;, &#39;杨不悔&#39;) as out_put;</code></li>
<li><code>select instr(&#39;杨不悔爱上了殷六侠&#39;, &#39;张无忌&#39;) as out_put;</code></li>
</ul>
<p><strong>2.6、trim、ltrim、rtrim</strong> 常用来去掉首尾多余的空格（或指定字符）</p>
<ul>
<li><strong>trim([remstr FROM] str)</strong> 去掉首尾指定的字符，不指定就默认去掉空格<ul>
<li><font color="#e96900">select trim(&quot;&amp;ensp;&amp;ensp;&amp;ensp;张翠山&amp;ensp;&amp;ensp;&quot;) as result;</font></li>
<li><font color="#e96900">select trim(&quot;a&quot; FROM &#39;aa张aa翠山aaa&#39;) as result;</font></li>
<li><font color="#e96900">select trim(&quot;aa&quot; FROM &#39;aaa张aa翠山aaaa&#39;) as result;</font></li>
<li><font color="#e96900">select trim(&quot;ab&quot; FROM &#39;abab张ab翠山abab&#39;) as result;</font></li>
</ul>
</li>
<li><strong>trim([{BOTH | LEADING | TRAILING} [remstr] FROM] str)</strong> 去掉首尾指定的字符，不指定就默认去掉空格，“BOTH”表示去掉首尾，“LEADING”表示只去首，“TRAILING”表示只去尾<ul>
<li><font color="#e96900">select trim(both from &quot;&amp;ensp;&amp;ensp;&amp;ensp;张翠山&amp;ensp;&amp;ensp;&quot;) as result;</font></li>
<li><font color="#e96900">select trim(leading &quot;a&quot; FROM &#39;aa张aa翠山aaa&#39;) as result;</font></li>
<li><font color="#e96900">select trim(both &quot;aa&quot; FROM &#39;aaa张aa翠山aaaa&#39;) as result;</font></li>
<li><font color="#e96900">select trim(trailing &quot;ab&quot; FROM &#39;abab张ab翠山abab&#39;) as result;</font></li>
</ul>
</li>
<li><strong>ltrim(str)</strong> 只能去掉首空格，并不能像上面一样去掉指定字符<ul>
<li><font color="#e96900">select trim(&quot;&amp;ensp;&amp;ensp;&amp;ensp;张翠山&amp;ensp;&amp;ensp;&quot;) as result;</font></li>
</ul>
</li>
<li><strong>rtrim(str)</strong> 只能去掉尾空格，并不能像上面一样去掉指定字符<ul>
<li><font color="#e96900">select trim(&quot;&amp;ensp;&amp;ensp;&amp;ensp;张翠山&amp;ensp;&amp;ensp;&quot;) as result;</font></li>
</ul>
</li>
</ul>
<p><strong>2.7、lpad(str, len, padstr)</strong> 用指定的字符实现左填充到指定长度，如果本身字符个数就超过了指定长度，那就类似于substr()直接截断</p>
<ul>
<li><code>select lpad(&#39;殷素素&#39;, 10, &#39;*&#39;) as result;</code> 结果“*******殷素素”</li>
<li><code>select lpad(&#39;殷素素&#39;, 2, &#39;*&#39;) as result;</code> 结果“殷素”</li>
<li><code>select lpad(&#39;殷素素&#39;, 10, &#39;ab&#39;) as result;</code> 结果“abababa殷素素”</li>
</ul>
<p><strong>2.8、rpad(str, len, padstr)</strong> 用指定的字符实现右填充到指定长度，如果本身字符个数就超过了指定长度，那就类似于substr()直接截断</p>
<ul>
<li><code>select rpad(&#39;殷素素&#39;, 10, &#39;*&#39;) as result;</code> 结果“殷素素*******”</li>
<li><code>select rpad(&#39;殷素素&#39;, 2, &#39;*&#39;) as result;</code> 结果“殷素”</li>
<li><code>select rpad(&#39;殷素素&#39;, 10, &#39;ab&#39;) as result;</code> 结果“殷素素abababa”</li>
</ul>
<p><strong>2.9、replace(str, from_str, to_str)</strong> 实现字符替换</p>
<ul>
<li><code>select replace(&quot;张无忌爱上了周芷若&quot;, &#39;周芷若&#39;, &#39;赵敏&#39;) as result;</code></li>
<li><code>select replace(&quot;张无忌爱上了周芷若、周芷若、周芷若&quot;, &#39;周芷若&#39;, &#39;赵敏&#39;) as result;</code></li>
<li><code>select replace(012301230123, 1, 5) as result;</code> 结果为 “52305230523”</li>
<li><code>select replace(012301230123, 01, 5) as result;</code> 结果为 “52305230523”</li>
<li><code>select replace(012301230123, 01, 05) as result;</code> 结果为 “52305230523”</li>
<li><code>select replace(012301230123, 1, 0) as result;</code> 结果为 “02300230023”</li>
</ul>
</blockquote>
<p><strong>3、数学函数</strong></p>
<blockquote>
<p><strong>3.1、round(X) &#x2F; round(X, D)</strong> 四舍五入，参数D表示小数点后保留D位数字，若D为负数，则表示保留小数点前的数字。round(X)与round(X, 0)效果一样</p>
<ul>
<li><code>select round(1.45) as result;</code> 结果为 1</li>
<li><code>select round(&quot;1.45&quot;) as result;</code> 可以直接传入字符型</li>
<li><code>select round(1.65) as result;</code> 结果为 2</li>
<li><code>select round(-1.45) as result;</code> 结果为 -1</li>
<li><code>select round(-1.65) as result;</code> 结果为 -2</li>
<li><code>select round(1.45, 0) as result;</code> 结果为 1</li>
<li><code>select round(1.65, 0) as result;</code> 结果为 2</li>
<li><code>select round(1.567, 2) as result;</code> 结果为 1.57</li>
<li><code>select round(-1.567, 2) as result;</code> 结果为 -1.57</li>
<li><code>select round(123.567, -2) as result;</code> 结果为 100</li>
<li><code>select round(-123.567, -2) as result;</code> 结果为 -100</li>
<li><code>select round(154.567, -2) as result;</code> 结果为 200</li>
<li><code>select round(-154.567, -2) as result;</code> 结果为 -200</li>
<li><code>select round(300.567, -3) as result;</code> 结果为 0</li>
<li><code>select round(500.567, -3) as result;</code> 结果为 1000</li>
<li><code>select round(300.567, -4) as result;</code> 结果为 0</li>
<li><code>select round(500.567, -4) as result;</code> 结果为 0</li>
</ul>
<p><strong>3.2、ceil(X) &#x2F; ceiling(X)</strong> 向上取整，返回大于等于X的最小整数值</p>
<ul>
<li><code>select ceil(1.45) as result;</code> 结果为 2</li>
<li><code>select ceil(-1.45) as result;</code> 结果为 -1</li>
</ul>
<p><strong>3.3、floor(X)</strong> 向下取整，返回小于等于X的最大整数值</p>
<ul>
<li><code>select floor(1.45) as result;</code> 结果为 1</li>
<li><code>select floot(-1.45) as result;</code> 结果为 -2</li>
</ul>
<p><strong>3.4、truncate(X,D)</strong> 截断，参数D表示小数点后保留D为数字，若D为负数，则表示保留小数点前的数字。truncate(X, 0)表示取整</p>
<ul>
<li><code>select truncate(1.99999, 3) as result;</code> 结果为 1.999</li>
<li><code>select truncate(1.99999, 0) as result;</code> 结果为 1</li>
<li><code>select truncate(1234.99999, -1) as result;</code> 结果为 1230</li>
<li><code>select truncate(1234.99999, -2) as result;</code> 结果为 1200</li>
<li><code>select truncate(1234.99999, -3) as result;</code> 结果为 1000</li>
<li><code>select truncate(1234.99999, -4) as result;</code> 结果为 0</li>
<li><code>select truncate(-1234.99999, -3) as result;</code> 结果为 -1000</li>
</ul>
<p><strong>3.5、mod(N, M)</strong> 取余。表示 N &#x2F; M 的余数，不管N、M是正数还是负数，都满足“余数 &#x3D; N - M*商”，因为余数就是这么定义的。其实也可以看被除数，被除数N为正，余数就为正；被除数N为负，余数就为负。</p>
<ul>
<li><code>select mod(8, 5) as result;</code> 结果为 3</li>
<li><code>select mod(8, -5) as result;</code> 结果为 3</li>
<li><code>select mod(-8, 5) as result;</code> 结果为 -3</li>
<li><code>select mod(-8, -5) as result;</code> 结果为 -3</li>
<li><code>select mod(5, 8) as result;</code> 结果为 5</li>
</ul>
</blockquote>
<p><strong>4、日期函数</strong></p>
<blockquote>
<p><strong>4.1、now()</strong> 返回当前系统日期 + 时间</p>
<ul>
<li><code>select now() as result;</code></li>
</ul>
<p><strong>4.2、curdate()</strong> 返回当前系统日期，不包含时间</p>
<ul>
<li><code>select curdate() as result;</code></li>
</ul>
<p><strong>4.3、curtime()</strong> 返回当前系统时间，不包含日期</p>
<ul>
<li><code>select curtime() as result;</code></li>
</ul>
<p><strong>4.4、year(date)、month(date)、day(date)、hour(time)、second(time)、minute(time)</strong> 获取指定的部分：年、月、日、时、分、秒</p>
<ul>
<li><code>select year(now()), year(curdate()), year(curtime());</code></li>
<li><code>select year(&quot;2021-10-11 10:46:27&quot;), year(&quot;2021-10-11&quot;)</code></li>
<li><code>select month(now()), month(curdate()), month(curtime());</code></li>
<li><code>select monthname(now()), monthname(curdate()), monthname(curtime());</code> 结果为月份的英文名</li>
<li><code>select month(&quot;2021-10-11 10:46:27&quot;), month(&quot;2021-10-11&quot;)</code></li>
<li><code>select day(now()), day(curdate()), day(curtime());</code></li>
<li><code>select day(&quot;2021-10-11 10:46:27&quot;), day(&quot;2021-10-11&quot;);</code></li>
<li><code>select hour(now()), hour(curtime());</code></li>
<li><code>select hour(&quot;2021-10-11 10:46:27&quot;), hour(&quot;10:46:27&quot;);</code></li>
<li><code>select minute(now()), minute(curtime());</code></li>
<li><code>select minute(&quot;2021-10-11 10:46:27&quot;), minute(&quot;10:46:27&quot;);</code></li>
<li><code>select second(now()), second(curtime());</code></li>
<li><code>select second(&quot;2021-10-11 10:46:27&quot;), second(&quot;10:46:27&quot;);</code></li>
<li>案例1：查询员工的入职年份，并升序排序<ul>
<li><code>select year(hiredate) from employees order by hiredate;</code></li>
</ul>
</li>
</ul>
<p><strong>4.5、str_to_date(str, format)</strong> 将日期格式的字符转换成指定格式的日期</p>
<ul>
<li><code>select str_to_date(&#39;2021-10-11 10:46:27&#39;, &#39;%Y-%m-%d&#39;);</code> 结果为“2021-10-11”</li>
<li><code>select str_to_date(&#39;2021-10-11 10:46:27&#39;, &#39;%Y-%m-%d %H:%i:%s&#39;);</code> 结果为“2021-10-11 10:46:27”</li>
<li><table>
<thead>
<tr>
<th>序号</th>
<th>格式符</th>
<th>功能</th>
</tr>
</thead>
<tbody><tr>
<td>1</td>
<td>%Y</td>
<td>4位的年份</td>
</tr>
<tr>
<td>2</td>
<td>%y</td>
<td>2位的年份</td>
</tr>
<tr>
<td>3</td>
<td>%m</td>
<td>月份（01,02,…,11,12）</td>
</tr>
<tr>
<td>4</td>
<td>%c</td>
<td>月份（1,2,…,11,12）</td>
</tr>
<tr>
<td>5</td>
<td>%d</td>
<td>日（01,02,…）</td>
</tr>
<tr>
<td>6</td>
<td>%H</td>
<td>小时（24小时制）</td>
</tr>
<tr>
<td>7</td>
<td>%h</td>
<td>小时（12小时制）</td>
</tr>
<tr>
<td>8</td>
<td>%i</td>
<td>分钟（00,01,…,58,59）</td>
</tr>
<tr>
<td>9</td>
<td>%s</td>
<td>秒（00,01,…,58,59）</td>
</tr>
</tbody></table>
</li>
<li>案例1：查询入职日期为“1992-4-3”的员工信息<ul>
<li><code>SELECT * FROM employees WHERE hiredate=&#39;1992-4-3&#39;;</code></li>
<li><code>SELECT * FROM employees WHERE hiredate=str_to_date(&#39;4-3 1992&#39;, &#39;%c-%d %Y&#39;);</code></li>
</ul>
</li>
</ul>
<p><strong>4.6、data_format(date, format)</strong> 将日期转换成指定格式的字符</p>
<ul>
<li><code>select date_format(now(), &#39;%Y年%m月%d日 %H时%i分%s秒&#39;);</code></li>
<li><code>select date_format(now(), &#39;%H:%i:%s秒 %m月%d日%Y年&#39;);</code></li>
<li><code>select date_format(curtime(), &#39;%Y年%m月%d日 %H时%i分%s秒&#39;);</code></li>
<li><code>select date_format(&#39;2021-10-11 10:46:27&#39;, &#39;%Y年%m月%d日 %H时%i分%s秒&#39;);</code></li>
<li>案例1：查询有奖金的员工名和入职日期(xx月&#x2F;xx日&#x2F; xx年)<ul>
<li><code>select last_name, date_format(hiredate, &#39;%m月/%d日 %y年&#39;) 入职日期 from employees where commission_pct is not null;</code></li>
</ul>
</li>
</ul>
</blockquote>
<p><strong>5、其他函数</strong></p>
<blockquote>
<ul>
<li><font color="#e96900" size="5">select version();</font></li>
<li><font color="#e96900" size="5">select database();</font></li>
<li><font color="#e96900" size="5">select user();</font></li>
</ul>
</blockquote>
<p><strong>6、流程控制函数</strong></p>
<blockquote>
<p><strong>6.1、if(expr1, expr2, expr3)</strong> 可以实现类似于if else的效果，与三元运算符很像。表达式expr1成立，则返回表达式expr2的值，否则返回表达式expr3的值</p>
<ul>
<li><code>select if(10&gt;5, &quot;大&quot;, &#39;小&#39;) as result;</code></li>
<li><code>select if(10&lt;5, &quot;大&quot;, &#39;小&#39;) as result;</code></li>
<li>案例1：查询员工有无奖金，分别给有无奖金做个备注<ul>
<li><code>select last_name, commission_pct, if(commission_pct is null, &#39;没奖金，呵呵&#39;, &#39;有奖金，嘻嘻&#39;) 备注 from employees;</code></li>
</ul>
</li>
</ul>
<p><strong>6.2 case 的使用</strong></p>
<ul>
<li><p><strong>使用一：switch case 的效果</strong></p>
<table>
<thead>
<tr>
<th>java中</th>
<th>mysql中</th>
</tr>
</thead>
<tbody><tr>
<td>switch (变量或表达式) {<br>  case 常量1: 语句1; break;<br>  …<br>  defualt: 语句n; break;<br>}</td>
<td>case 要判断的字段、变量或表达式 <br>when 常量1 then 要显示的值1或 语句1;<br>when 常量2 then 要显示的值2或 语句2;<br>…<br>else 要显示的值n或 语句n;<br>end</td>
</tr>
</tbody></table>
<blockquote>
<p>案例1：查询员工的工资，要求①部门号&#x3D;30，显示的工资为1.1倍；②部门号&#x3D;40，显示的工资为1.2倍；③部门号&#x3D;50，显示的工资为1.3倍；④其他部门，显示的工资为原工资</p>
<ul>
<li><font color="#e96900">select salary 原始工资, department_id,<br>(CASE department_id<br>WHEN 30 THEN salary * 1.1<br>WHEN 40 THEN salary * 1.2<br>WHEN 50 THEN salary * 1.3<br>ELSE salary<br>END) as 新工资<br>from employees;</font></li>
</ul>
</blockquote>
</li>
<li><p><strong>使用二：类似于 多重if</strong></p>
<table>
<thead>
<tr>
<th>java中</th>
<th>mysql中</th>
</tr>
</thead>
<tbody><tr>
<td>if (条件1) { 语句1; }<br>else if (条件2) { 语句2; }<br>…<br>else { 语句n; }</td>
<td>case<br>when 条件1 then 要显示的值1或 语句1;<br>when 条件2 then 要显示的值2或 语句2;<br>…<br>else 要显示的值n或 语句n;<br>end</td>
</tr>
</tbody></table>
<blockquote>
<p>案例2：查询员工的工资情况，要求①如果工资&gt;2000，显示级别A；②如果工资&gt;15000，显示级别B；③如果工资&gt;10000，显示级别C；④其他工资显示级别D</p>
<ul>
<li><font color="#e96900">select salary,<br>(CASE<br>WHEN salary&gt;20000 THEN &#39;A&#39;<br>WHEN salary&gt;15000 THEN &#39;B&#39;<br>WHEN salary&gt;10000 THEN &#39;C&#39;<br>ELSE &#39;D&#39;<br>END) as 工资级别<br>from employees;</font></li>
</ul>
</blockquote>
</li>
</ul>
</blockquote>
<p><strong>7、分组函数</strong><br>  <strong>sum([distinct] expr) 求和</strong>、<strong>avg([distinct] expr) 平均值</strong>、<strong>max([distinct] expr) 最大值</strong>、<strong>min([distinct] expr) 最小值</strong>、<strong>count(expr)&#x2F;count(distinct expr,[expr…]) 计算个数</strong></p>
<blockquote>
<p><strong>7.1、分组函数简单使用</strong></p>
<ul>
<li><code>select sum(salary) from employees as &quot;sum&quot;;</code></li>
<li><code>select avg(salary) from emploees as &quot;avg&quot;;</code></li>
<li><code>select max(salary) from employees as &quot;max&quot;;</code></li>
<li><code>select min(salary) from employees as &quot;min&quot;;</code></li>
<li><code>select count(salary) from emploees as &quot;count&quot;;</code></li>
<li><code>select count(distinct salary) from employees as &quot;distinct count&quot;;</code></li>
<li><code>select sum(salary), avg(salary), max(salary), min(salary), count(salary) from employees;</code></li>
<li>案例1：查询员工表中的最大入职时间和最小入职时间的相差天数<ul>
<li><code>select DATEDIFF(max(hiredate), min(hiredate)) as diffrence from employees;</code></li>
</ul>
</li>
</ul>
<p><strong>7.2、分组函数支持的参数类型</strong></p>
<ul>
<li>虽然不报错，但是结果无意义<ul>
<li><code>select sum(last_name), avg(last_name) from employees;</code> 全部返回 0</li>
<li><code>select sum(hiredate), avg(hiredate) from employees;</code></li>
</ul>
</li>
<li>结果有意义<ul>
<li><code>select max(last_name), min(last_name), count(last_name) from employees;</code></li>
<li><code>select max(hiredate), min(hiredate), count(hiredate) from employees;</code></li>
</ul>
</li>
<li>注意count()并不统计 null 值<ul>
<li><code>select count(last_name), count(commission_pct) from employees;</code></li>
<li><code>select count(*), count(commission_pct), count(distinct commission_pct) from employees;</code></li>
</ul>
</li>
<li>总结：<ul>
<li>sum、avg 一般用于处理数值型</li>
<li>max、min 可以处理任何可排序类型</li>
<li>count 可以处理任何类型，但是不能统计到 null 值，而且默认不去重，会重复统计，使用 “distinct” 可以实现去重统计</li>
</ul>
</li>
</ul>
<p><strong>7.3、分组函数是否忽略 null 值</strong></p>
<ul>
<li><code>select sum(commission_pct), avg(commission_pct) from employees;</code></li>
<li><code>select avg(commission_pct), sum(commission_pct)/count(*), sum(commission_pct)/count(commission_pct) from employees;</code></li>
<li><code>select max(commission_pct), min(commission_pct) from employees;</code></li>
<li><code>select count(*), count(commission_pct), count(distinct commission_pct) from employees;</code><ul>
<li>计算sum()时，null值根本就不参与运算，因为 “null+任何” 结果都为null</li>
<li>计算avg()时，null值也不参与运算，忽略 null 值</li>
<li>计算max()和min时，null值也不参与运算，忽略 null 值</li>
<li>计算count()时，null值也不参与运算，忽略 null 值，而且默认不去重，会重复统计，使用 “distinct” 可以实现去重统计</li>
</ul>
</li>
<li>总结：以上分组函数都会忽略 null 值</li>
</ul>
<p><strong>7.4、分组函数可以和 “distinct” 关键字搭配使用，实现去重</strong></p>
<ul>
<li><code>select sum(commission_pct), sum(distinct commission_pct) from employees;</code></li>
<li><code>select avg(commission_pct), avg(distinct commission_pct), sum(commission_pct)/count(commission_pct),  sum(distinct commission_pct)/count(distinct commission_pct)from employees;</code></li>
<li><code>select max(commission_pct), max(distinct commission_pct) from employees;</code></li>
<li><code>select min(commission_pct), min(distinct commission_pct) from employees;</code></li>
<li><code>select count(*), count(commission_pct), count(distinct commission_pct) from employees;</code></li>
</ul>
<p><strong>7.5、专门介绍一下 count()</strong></p>
<ul>
<li><strong>count(*)</strong>  有效统计总行数。每行数据中，总有一个字段不为 null<ul>
<li><code>select count(*) from employees;</code></li>
</ul>
</li>
<li><strong>count(1)</strong>  也能有效统计总行数。相当于给每行多加了一列，这一列的值为 1，然后统计有多少个 1。<ul>
<li><code>select count(1) from employees;</code></li>
<li><code>select count(2) from employees;</code> 这样也是可以的</li>
<li><code>selecy count(&quot;哈哈哈&quot;) from employees;</code></li>
</ul>
</li>
<li><strong>行数统计效率</strong><ul>
<li>MYISAM存储引擎下，count(*) 的效率最高，因为有记录行数的变量</li>
<li>INNODB存储引擎下，count(*) 和 count(1) 的效率差不多，比 count(字段) 要高，因为 count(字段) 需要判断是否为 null 值，有个筛选的过程</li>
<li>一般使用 count(*) 统计行数</li>
</ul>
</li>
</ul>
<p><strong>7.6、和分组函数一同查询的字段有限制</strong></p>
<ul>
<li><code>select AVG(salary), employee_id from employees;</code> 不报错，能执行，但是结果无意义</li>
<li>和分组函数一同查询的字段要求是 group by 后的字段，其他的都不行</li>
</ul>
</blockquote>
<h4 id="E、分组查询"><a href="#E、分组查询" class="headerlink" title="E、分组查询"></a>E、分组查询</h4><p><strong>1、语法</strong></p>
<blockquote>
<p><font color="#e96900">SELECT 分组函数, 其他列(要求出现在group by的后面)<br>FROM 表名<br>[WHERE 筛选条件]<br>GROUP BY 分组的列表<br>[ORDER BY 排序列表[asc|desc]]</font><br><strong>where 一定要放在 from 后面</strong><br><strong>查询列表有点特殊，要求是分组函数和group by后出现的字段</strong></p>
</blockquote>
<p><strong>2、简单使用</strong></p>
<blockquote>
<p>案例1：查询每个部门的平均工资</p>
<ul>
<li><font color="#e96900" size="4">select department_id, avg(salary)<br>from employees<br>group by department_id;</font></li>
</ul>
<p>案例2：查询每个工种的最高工资</p>
<ul>
<li><font color="#e96900" size="4">select job_id, max(salary)<br>from employees<br>group by job_id;</font></li>
</ul>
<p>案例3：查询每个位置上的部门个数</p>
<ul>
<li><font color="#e96900" size="4">select location_id, count(*)<br>from departments<br>group by location_id;</font></li>
</ul>
</blockquote>
<p><strong>3、按多字段分组</strong></p>
<blockquote>
<p>案例1：查询每个部门每个工种的平均工资</p>
<ul>
<li><font color="#e96900" size="4">select avg(salary), department_id, job_id<br>from employees<br>group by department_id, job_id;</font></li>
<li><font color="#e96900" size="4">select avg(salary), department_id, job_id<br>from employees<br>group by job_id, department_id;</font></li>
</ul>
</blockquote>
<p><strong>4、添加分组前筛选，其筛选源是 原始表，放在 group by 子句的前面，使用 where 关键字。能在分组前筛选的优先使用分组前筛选。</strong></p>
<blockquote>
<p>案例1：查询邮箱中包含 ‘a’ 字符的，每个部门的平均工资</p>
<ul>
<li><font color="#e96900" size="4">select avg(salary), department_id<br>from employees<br>where email like &#39;%a%&#39;<br>group by department_id;</font></li>
</ul>
<p>案例2：查询有奖金的每个领导手下员工的最高工资</p>
<ul>
<li><font color="#e96900" size="4">select max(salary), manager_id<br>from employees<br>where commission_pct is not null<br>group by manager_id;</font></li>
</ul>
</blockquote>
<p><strong>5、添加分组后筛选，其筛选源是 分组后的结果集，放在 group by 子句的后面，使用 having 关键字。筛选条件涉及到分组函数的，一定是使用分组后筛选，也就是使用 having 来筛选</strong></p>
<blockquote>
<p>案例1：查询哪些部门的员工个数 &gt; 2</p>
<ul>
<li><font color="#e96900" size="4">select count(*), department_id<br>from employees<br>group by department_id<br>having count(*) &gt; 2;</font></li>
</ul>
<p>案例2：查询每个工种有奖金的员工的最高工资&gt;12000的工种编号和最高工资</p>
<ul>
<li><font color="#e96900" size="4">select job_id, max(salary)<br>from employees<br>where commission_pct is not null<br>group by job_id<br>having max(salary) &gt; 12000;</font></li>
</ul>
<p>案例3：查询领导编号 &gt; 102的每个领导手下员工的最低工资 &gt; 5000的领导编号是哪个，以及其员工最低工资</p>
<ul>
<li><font color="#e96900" size="4">select min(salary), manager_id<br>from employees<br>where manager_id &gt; 102<br>group by manager_id<br>having min(salary) &gt; 5000;</font></li>
</ul>
</blockquote>
<p><strong>6、按函数分组</strong></p>
<blockquote>
<p>案例1：按员工姓名的长度分组，查询每一组的员工个数，筛选员工个数 &gt; 5的有哪些</p>
<ul>
<li><font color="#e96900" size="4">select count(*), length(last_name) len_name<br>from employees<br>group by length(last_name)<br>having count(*) &gt; 5;</font></li>
<li><font color="#e96900" size="4">select count(*) c, length(last_name) len_name<br>from employees<br>group by len_name<br>having c &gt; 5;</font></li>
</ul>
</blockquote>
<p><strong>7、添加排序</strong></p>
<blockquote>
<p>案例1：查询每个部门每个工种的员工的平均工资，并且按平均工资的高低显示</p>
<ul>
<li><font color="#e96900" size="4">select avg(salary), department_id, job_id<br>from employees<br>group by department_id, job_id<br>order by avg(salary) desc;</font></li>
</ul>
<p>案例2：查询不为null的每个部门每个工种的员工的平均工资，并且按平均工资的高低显示</p>
<ul>
<li><font color="#e96900" size="4">select avg(salary), department_id, job_id<br>from employees<br>where department_id is not null and job_id is not null<br>group by department_id, job_id<br>order by avg(salary) desc;</font></li>
</ul>
</blockquote>
<h4 id="F、连接查询"><a href="#F、连接查询" class="headerlink" title="F、连接查询"></a>F、连接查询</h4><p>  连接查询又称为多表查询，当查询的字段来自于多个表时，就会用到连接查询。笛卡尔乘积现象：表1有m行，表2有n行，结果&#x3D;m*n行。发生的原因：没有有效的连接条件。如何避免：添加有效的连接条件。</p>
<p><strong>1、分类</strong></p>
<blockquote>
<p>按年代分类：</p>
<ul>
<li>sql92标准（在mysql中仅仅支持内连接）</li>
<li>sql99标准【推荐】（在mysql中支持内连接、外连接(左外和右外)、交叉连接）</li>
</ul>
<p>按功能分类：</p>
<ul>
<li>内连接（等值连接、非等值连接、自连接）</li>
<li>外连接（左外连接、右外连接、全外连接）</li>
<li>交叉连接</li>
</ul>
</blockquote>
<p><strong>2、sql92语法，内连接</strong></p>
<blockquote>
<p><strong>2.1、语法</strong></p>
<blockquote>
<p><font color="#e96900" size="4">select 查询列表<br>from 表1, 表2, …<br>where 等值连接条件<br>[and 筛选条件]<br>[GROUP BY 分组的列表]<br>[ORDER BY 排序列表[asc|desc]]</font></p>
</blockquote>
<p><strong>2.2、等值连接</strong></p>
<blockquote>
<p><strong>① 简单等值连接</strong></p>
<ul>
<li>案例1：查询女神名和对应的男神名<ul>
<li><font color="#e96900">SELECT name, boyName<br>  FROM beauty, boys<br>  WHERE beauty.boyfriend_id &#x3D; boys.id;</font></li>
</ul>
</li>
</ul>
<p><strong>② 表的顺序可以交换</strong></p>
<ul>
<li>案例1：查询员工名和对应的部门名<ul>
<li><font color="#e96900">SELECT name, boyName<br>  FROM beauty, boys<br>  WHERE beauty.boyfriend_id &#x3D; boys.id;</font></li>
</ul>
</li>
</ul>
<p><strong>③ 为表取别名</strong></p>
<ul>
<li>案例1：查询员工名、工种号、工种名<ul>
<li><font color="#e96900">select last_name, emp.job_id, job_title<br>  from employees emp, jobs j<br>  where emp.job_id &#x3D; j.job_id;</font></li>
</ul>
</li>
<li>取别名①提高语句的简洁度，②区分多个重名的字段</li>
<li><strong>注意：</strong> 如果为表起了别名，则查询的字段就不能使用原来的表名去限定</li>
</ul>
<p><strong>④ 加筛选条件</strong></p>
<ul>
<li>案例1：查询有奖金的员工名、部门名<ul>
<li><font color="#e96900">select last_name, department_name, commission_pct<br>  from employees e, departments d<br>  where e.department_id&#x3D;d.department_id<br>  AND e.commission_pct is not null;</font></li>
</ul>
</li>
<li>案例2：查询城市名中第二个字符为’o’的部门名和城市<ul>
<li><font color="#e96900">select department_name, city<br>  from departments d, locations l<br>  where d.location_id &#x3D; l.location_id<br>  AND city like &quot;_o%&quot;;</font></li>
</ul>
</li>
</ul>
<p><strong>⑤ 加分组</strong></p>
<ul>
<li>案例1：查询每个城市的部门个数<ul>
<li><font color="#e96900">select count(*) 个数, city<br>  from departments d, locations l<br>  where d.location_id &#x3D; l.location_id<br>  group by city;</font></li>
</ul>
</li>
<li>案例2：查询有奖金的每个部门的部门名和部门的领导编号和该部门的最低工资<ul>
<li><font color="#e96900">select department_name, d.manager_id, min(salary)<br>  from departments d, employees e<br>  where d.department_id &#x3D; e.department_id<br>  AND commission_pct IS NOT NULL<br>  GROUP BY department_name, d.manager_id;</font></li>
</ul>
</li>
</ul>
<p><strong>⑥ 加排序</strong></p>
<ul>
<li>案例1：查询出每个工种的工种名和员工的个数，并且按员工个数降序<ul>
<li><font color="#e96900">select job_title, count(*)<br>  from employees e, jobs j<br>  where e.job_id &#x3D; j.job_id<br>  group by job_title<br>  order by count(*) desc;</font></li>
</ul>
</li>
</ul>
<p><strong>⑦ 多表连接</strong></p>
<ul>
<li>案例1：查询员工名、部门名和所在城市<ul>
<li><font color="#e96900">select last_name, department_name, city<br>  from employees e, departments d, locations l<br>  where e.department_id &#x3D; d.department_id<br>  and d.location_id &#x3D; l.location_id;</font></li>
</ul>
</li>
<li>案例2：继续加条件和排序<ul>
<li><font color="#e96900">select last_name, department_name, city<br>  from employees e, departments d, locations l<br>  where e.department_id &#x3D; d.department_id<br>  and d.location_id &#x3D; l.location_id<br>  and city like &quot;s%&quot;<br>  order by department_name desc;</font></li>
</ul>
</li>
</ul>
<p><strong>⑧ 等值连接总结</strong></p>
<ul>
<li>多表等值连接的结果为多表的交集部分</li>
<li>n 表连接，至少需要 n-1 个连接条件</li>
<li>多表的顺序没有要求</li>
<li>一般需要为表起别名</li>
<li>可以搭配排序、分组、筛选等子句一同使用</li>
</ul>
</blockquote>
<p><strong>2.3、非等值连接</strong></p>
<blockquote>
<p><strong>① 简单非等值连接</strong></p>
<ul>
<li>案例1：查询员工的工资和工资级别<ul>
<li><font color="#e96900">select salary, grade_level<br>  from employees e, job_grades g<br>  where salary between lowest_sal and highest_sal;</font></li>
</ul>
</li>
</ul>
<p><strong>② 加入其它筛选条件</strong></p>
<ul>
<li>案例1：查询员工的工资级别为’A’或者’B’的工资<ul>
<li><font color="#e96900">select salary, grade_level<br>  from employees e, job_grades g<br>  where salary between lowest_sal and highest_sal<br>  and grade_level in (&#39;A&#39;, &#39;B&#39;);</font></li>
</ul>
</li>
</ul>
</blockquote>
<p><strong>2.4、自连接</strong></p>
<blockquote>
<p><strong>① 简单自连接</strong></p>
<ul>
<li>案例1：查询员工和上级的名称<ul>
<li><font color="#e96900">select e.employee_id, e.last_name 员工名, m.employee_id, m.last_name 上级名<br>  from employees e, employees m<br>  where e.manager_id &#x3D; m.employee_id;</font></li>
</ul>
</li>
</ul>
</blockquote>
</blockquote>
<p><strong>3、sql99语法，内连接</strong></p>
<blockquote>
<p><strong>3.1、语法</strong><br><font color="#e96900">select 查询列表<br>from 表1 别名 【连接类型】join 表2 别名 on 连接条件<br>【where 筛选条件】<br>【group by 分组】<br>【having 筛选条件】<br>【order by 排序字段 【asc|desc】】</font></p>
<blockquote>
<p><strong>其中连接类型：</strong></p>
<ul>
<li>内连接：<strong>inner</strong></li>
<li>左外连接：<strong>left [outer]</strong></li>
<li>右外连接：<strong>right [outer]</strong></li>
<li>全外连接：<strong>full [outer]</strong></li>
<li>交叉连接：<strong>cross</strong></li>
</ul>
</blockquote>
<p><strong>3.2、等值连接（inner可省略）</strong></p>
<blockquote>
<ul>
<li><p>案例1：查询员工名、部门名</p>
<ul>
<li><font color="#e96900">select last_name, department_name<br>  from employees e<br>  inner join departments d<br>  on e.department_id &#x3D; d.department_id;</font></li>
<li><font color="#e96900">select last_name, department_name<br>  from departments d<br>  inner join employees e<br>  on e.department_id &#x3D; d.department_id;</font></li>
</ul>
</li>
<li><p>案例2：查询名字中包含’e’的员工名和工种名（添加筛选）</p>
<ul>
<li><font color="#e96900">select last_name, job_title<br>  from employees e<br>  inner join jobs j<br>  on e.job_id &#x3D; j.job_id<br>  where last_name like &#39;e&#39;;</font></li>
</ul>
</li>
<li><p>案例3：查询部门个数 &gt;3 的城市名和部门个数（分组+筛选）</p>
<ul>
<li><font color="#e96900">select city, count(*) 部门个数<br>  from departments d<br>  inner locations l<br>  on d.location_id &#x3D; l.location_id<br>  group by city<br>  where count(*) &gt; 3;</font></li>
</ul>
</li>
<li><p>案例四：查询哪个部门的部门员工个数 &gt;3 的部门名和员工个数，并按个数排序（排序）</p>
<ul>
<li><font color="#e96900">select e.department_id, d.department_name, count(*) 个数<br>  from employees e<br>  inner join departments d on e.department_id &#x3D; d.department_id<br>  group by department_id<br>  having count(*) &gt; 3<br>  order by count(*) desc;</font></li>
</ul>
</li>
<li><p>案例5：查询员工名、部门名、工种名，并按部门名降序（多表连接）</p>
<ul>
<li><font color="#e96900">select last_name, department_name, job_title<br>  from employees e<br>  inner join departments d on e.department_id &#x3D; d.department_id<br>  inner join jobs j on e.job_id &#x3D; j.job_id<br>  order by department_name desc;</font></li>
</ul>
</li>
</ul>
</blockquote>
<p><strong>3.3、非等值连接（inner可省略）</strong></p>
<blockquote>
<ul>
<li><p>案例1：查询员工的工资级和工资级别</p>
<ul>
<li><font color="#e96900">select salary, grade_level<br>  from employees e<br>  inner join job_grades g<br>  on e.salary between g.lowest_sal and g.highest_sal;</font></li>
</ul>
</li>
<li><p>案例2：查询员工的工资级别为’A’或者’B’的工资（加入筛选条件）</p>
<ul>
<li><font color="#e96900">select salary, grade_level<br>  from employees e<br>  inner join job_grades g on salary between lowest_sal and highest_sal<br>  where grade_level in (&#39;A&#39;, &#39;B&#39;);</font></li>
</ul>
</li>
<li><p>案例3：查询每个工资级别的个数，并按照工资级别降序（加入分组排序）</p>
<ul>
<li><font color="#e96900">select grade_level, count(*)<br>  from employees e<br>  inner join job_grades g on salary between lowest_sal and highest_sal<br>  group by grade_level<br>  order by grade_level desc;</font></li>
</ul>
</li>
</ul>
</blockquote>
<p><strong>3.4、自连接（inner可省略）</strong></p>
<blockquote>
<ul>
<li>案例1：查询员工的名字、上级的名字<ul>
<li><font color="#e96900">select e.last_name 员工名, m.last_name 上级名<br>  from employees e<br>  inner join employees m on e.manager_id &#x3D; m.employee_id;</font></li>
</ul>
</li>
</ul>
</blockquote>
</blockquote>
<p><strong>4、外连接</strong><br>  应用场景：用于查询一个表中有，另一个表中没有的记录。特点：①、外连接的查询结果为主表中的所有记录，如果从表中有和它匹配的，则显示匹配的值，如果从表中没有和它匹配的，则显示null。外连接查询结果 &#x3D; 内连接结果 + 主表中有而从表中没有的记录。②、左外连接，left join 左边的是主表，右外连接，right join 右边的是主表。③、左外连接和右外连接交换连个表的顺序，可以实现同样的查询效果。④、全外连接 &#x3D; 内连接的结果 + 表1中有但表2没有的 + 表2中有但表1中没有的。<strong>但是mysql不支持全外连接的语法。</strong></p>
<blockquote>
<p>案例1：查询男朋友 不在男神表的女神名</p>
<ul>
<li><font color="#e96900">SELECT b.name, bo.*<br>FROM beauty b<br>LEFT OUTER JOIN boys bo ON b.boyfriend_id &#x3D; bo.id<br>WHERE bo.id IS NULL;</font></li>
</ul>
<p>案例2：查询哪个部门没有员工</p>
<ul>
<li><p>左外连接</p>
<ul>
<li><font color="#e96900">select d.*, e.employee_id<br>  from departments d<br>  left outer join employees e on d.department_id &#x3D; e.department_id<br>  where e.employee_id is null;</font></li>
</ul>
</li>
<li><p>右外连接</p>
<ul>
<li><font color="#e96900">select d.*, e.employee_id<br>  from employees e<br>  right outer join departments d on e.department_id &#x3D; d.department_id<br>  where e.employee_id is null;</font></li>
</ul>
</li>
</ul>
</blockquote>
<p><strong>5、交叉连接</strong><br>  sql99语法中的交叉连接类似于笛卡尔乘积。mysql中是支持交叉连接的语法的。</p>
<blockquote>
<p><font color="#e96900">select b.*, bo.*<br>from beauty b<br>cross join boys bo;</font></p>
</blockquote>
<p><strong>6、总结</strong></p>
<blockquote>
<p>sql92 和 sql99 相比</p>
<ul>
<li>功能：sql99支持的连接查询比较多</li>
<li>可读性：sql99实现了连接条件和筛选条件的分离，可读性较高</li>
</ul>
</blockquote>
<p><img src="/posts/b6041c1e/1.png"></p>
<h4 id="G、子查询"><a href="#G、子查询" class="headerlink" title="G、子查询"></a>G、子查询</h4><p>  含义：出现在其他语句（包括增删改）中的 select 语句，称为<strong>子查询</strong>或<strong>内查询</strong>。内部嵌套了其他select语句的查询称为<strong>主查询</strong>或<strong>外查询</strong>。</p>
<p><strong>1、分类</strong></p>
<blockquote>
<p><strong>按照子查询出现的位置：</strong></p>
<ul>
<li>select 后面</li>
<li>from 后面</li>
<li><font color="#990000"><strong>where 或 having 后面</strong></font></li>
<li>exists 后面（相关子查询）</li>
</ul>
<p><strong>按照结果集的行数不同：</strong></p>
<ul>
<li><font color="#990000"><strong>标量子查询</strong></font>（结果集只有一行一列，也叫作单行子查询）</li>
<li><font color="#990000"><strong>列子查询</strong></font>（结果集只有一列多行，或叫做多行子查询）</li>
<li>行子查询（结果集有一行多列，多行多列其实也行）</li>
<li>表子查询（结果集就可以很随意了，一般为多行多列）</li>
</ul>
<p><strong>用法限制：</strong></p>
<ul>
<li>select后面 仅仅支持标量子查询</li>
<li>from后面 支持表子查询</li>
<li><font color="#990000"><strong>where或having后面 支持标量子查询(单行)、列子查询(多行)</strong></font>、行子查询（较少使用）</li>
<li>exists后面 支持表子查询</li>
</ul>
<p><strong>用法特点：</strong></p>
<ul>
<li>子查询要放在小括号内部</li>
<li>子查询一般放在条件的右侧</li>
<li>标量子查询，一般搭配着单行操作符使用 “&gt;”、“&lt;”、“&gt;&#x3D;”、“&lt;&#x3D;”、“&#x3D;”、“&lt;&gt;”</li>
<li>列子查询，一般搭配着多行操作符使用 “in”、“any”、“some”、“all”</li>
<li>子查询的执行会优先于主查询的执行，主查询的条件用到了子查询的结果</li>
</ul>
</blockquote>
<p><strong>2、where或having 后面的标量子查询（单行子查询）</strong><br>  标量子查询返回的值就是一个单值，所以也称为单行子查询。</p>
<blockquote>
<p>案例1：谁的工资比 “Abel” 高</p>
<ul>
<li><font color="#e96900">select *<br>from employees<br>where salary &gt; (<strong>SELECT salary FROM employees WHERE last_name &#x3D; &quot;Abel&quot;</strong>);</font></li>
</ul>
<p>案例2：返回job_id与141号员工相同，salary比143号员工多的员工姓名，job_id和工资</p>
<ul>
<li><font color="#e96900">select last_name, job_id, salary<br>from employees<br>where job_id &#x3D; (<strong>select job_id from employees where employee_id &#x3D; 141</strong>)<br>and salary &gt; (<strong>select salary from employees where employee_id &#x3D; 143</strong>);</font></li>
</ul>
<p>案例3：返回公司工资最少的员工的last_name, job_id 和 salary</p>
<ul>
<li><font color="#e96900">select last_name, job_id, salary<br>from employees<br>where salary &#x3D; (<strong>select min(salary) from employees</strong>);</font></li>
</ul>
<p>案例4：查询最低工资大于50号部门最低工资的部门id和其最低工资</p>
<ul>
<li><font color="#e96900">select department_id, min(salary)<br>from employees<br>group by department_id<br>having min(salary) &gt; (<strong>select min(salary) from employees where department_id &#x3D; 50</strong>);</font></li>
</ul>
</blockquote>
<p><strong>3、where或having 后面的列子查询（多行子查询）</strong><br>  列子查询返回多行单列值，主查询会使用到一些<strong>多行比较操作符</strong>。当然包含这些多行操作符的查询往往可以使用其他的方式进行替换，使其可读性更高。</p>
<ul>
<li><table>
<thead>
<tr>
<th>多行比较操作符</th>
<th>含义</th>
<th>替换</th>
</tr>
</thead>
<tbody><tr>
<td>in &#x2F; not in</td>
<td>等于列表中的<strong>任意一个</strong></td>
<td>in()可以替换为“&#x3D;any()”；not int()可以替换为“&lt;&gt;all()”</td>
</tr>
<tr>
<td>any 或 some</td>
<td>和子查询返回的<strong>某一个</strong>值比较</td>
<td>“&lt;any()”可以替换为“&lt;max()”；“&gt;any()”可以替换为“&gt;min()”；“&#x3D;any()”可以替换为“in()”</td>
</tr>
<tr>
<td>all</td>
<td>和子查询返回的<strong>所有</strong>值比较</td>
<td>“&lt;all()”可以替换为“&lt;min()”；“&gt;all()”可以替换为“&gt;max()”</td>
</tr>
</tbody></table>
</li>
</ul>
<blockquote>
<p>案例1：返回 location_id 是 1400或1700的部门中的所有员工姓名</p>
<ul>
<li><font color="#e96900">select last_name<br>from employees<br>where department_id in (<br>  <strong>select department_id<br>  from departments<br>  where location_id in (1400, 1700)</strong><br>);</font></li>
<li><font color="#e96900">select last_name<br>from employees<br>where department_id &#x3D; any(<br>  <strong>select department_id<br>  from departments<br>  where location_id in (1400, 1700)</strong><br>);</font></li>
</ul>
<p>案例2：返回其他工种中比job_id为“IT_PROG”的工种任一工资低的员工的：工号、姓名、job_id、以及salary</p>
<ul>
<li><font color="#e96900">select employee_id, last_name, job_id, salary<br>from employees<br>where salary &lt; any(<br>  <strong>select distinct salary<br>  from employees<br>  where job_id &#x3D; &quot;IT_PROG&quot;</strong><br>) and job_id &lt;&gt; &quot;IT_PROG&quot;;</font></li>
<li><font color="#e96900">select employee_id, last_name, job_id, salary<br>from employees<br>where salary &lt; (<br>  <strong>select max(salary)<br>  from employees<br>  where job_id &#x3D; &quot;IT_PROG&quot;</strong><br>) and job_id &lt;&gt; &quot;IT_PROG&quot;;</font></li>
</ul>
<p>案例3：返回其他工种中比job_id为“IT_PROG”的工种所有工资低的员工的：工号、姓名、job_id、以及salary</p>
<ul>
<li><font color="#e96900">select employee_id, last_name, job_id, salary<br>from employees<br>where salary &lt; all(<br>  <strong>select distinct salary<br>  from employees<br>  where job_id &#x3D; &quot;IT_PROG&quot;</strong><br>) and job_id &lt;&gt; &quot;IT_PROG&quot;;</font></li>
<li><font color="#e96900">select employee_id, last_name, job_id, salary<br>from employees<br>where salary &lt; (<br>  <strong>select min(salary)<br>  from employees<br>  where job_id &#x3D; &quot;IT_PROG&quot;</strong><br>) and job_id &lt;&gt; &quot;IT_PROG&quot;;</font></li>
</ul>
</blockquote>
<p><strong>4、where或having 后面的行子查询</strong><br>  行子查询一般返回一行多列值，也可以是多行多列值。行子查询一般很少使用。</p>
<blockquote>
<p>案例1：查询员工编号最小并且工资最高的员工信息</p>
<ul>
<li><font color="#e96900">select *<br>from employees<br>where employee_id &#x3D; (<strong>select min(employee_id) from employees</strong>)<br>and salary &#x3D; (<strong>select max(salary) from employees</strong>);</font></li>
<li><font color="#e96900">select *<br>from employees<br>where (employee_id, salary) &#x3D; (<br>  <strong>select min(employee_id), max(salary)<br>  from employees</strong><br>);</font></li>
</ul>
</blockquote>
<p><strong>5、select 后面的子查询</strong><br>  select后面的子查询仅仅只支持标量子查询，返回值只能是单值。</p>
<blockquote>
<p>案例1：查询每个部门的员工个数</p>
<ul>
<li><font color="#e96900">select d.*, (<br>  select count(*)<br>  from employees e<br>  where e.department_id &#x3D; d.department_id<br>) as 员工个数<br>from departments d;</font></li>
</ul>
<p>案例1：查询员工号为102的员工的部门名</p>
<ul>
<li><font color="#e96900">select (<br>  select department_name<br>  from departments d<br>  inner join employees e on d.department_id &#x3D; e.department_id<br>  where e.employee_id&#x3D;102<br>) 部门名;</font></li>
</ul>
</blockquote>
<p><strong>6、from 后面的子查询</strong><br>  from后面的子查询一般是表子查询。该子查询结果直接充当一个新的数据表来使用，要求必须要起别名。</p>
<blockquote>
<p>案例1：查询每个部门的平均工资的工资等级</p>
<ul>
<li><font color="#e96900">select temp.*, grade_level<br>from (<br>  select department_id, avg(salary) avg_sal<br>  from employees<br>  group by department_id<br>) as temp<br>left join job_grades g on temp.avg_sal between g.lowest_sal and g.highest_sal;</font></li>
</ul>
</blockquote>
<p><strong>7、exists 后面的子查询</strong><br>  有时也称为相关子查询。用exists来判断后面的子查询是否存在结果，返回 1 或 0。</p>
<blockquote>
<p>案例1：查询有员工名的部门名</p>
<ul>
<li><font color="#e96900">select department_name<br>from departments d<br>where exists(<br>  select employee_id<br>  from employees e<br>  where e.department_id &#x3D; d.department_id<br>);</font></li>
<li><font color="#e96900">select department_name<br>from departments d<br>where d.department_id in (<br>  select distinct department_id<br>  from employees<br>);</font></li>
</ul>
<p>案例2：查询没有女朋友的男神信息</p>
<ul>
<li><font color="#e96900">select bo.*<br>from boys bo<br>where not exists(<br>  select id<br>  from beauty<br>  where boyfriend_id &#x3D; bo.id<br>);</font></li>
<li><font color="#e96900">select bo.*<br>from boys bo<br>where bo.id not in (<br>  select distinct boyfriend_id<br>  from beauty<br>);</font></li>
</ul>
</blockquote>
<p><strong>8、子查询案例</strong></p>
<blockquote>
<p>案例1：查询和‘Zlotkey’相同部门的员工姓名和工资</p>
<ul>
<li><font color="#e96900" size="3">select last_name, salary<br>from employees<br>where department_id &#x3D; (<br>  select department_id<br>  from employees<br>  where last_name &#x3D; &quot;Zlotkey&quot;<br>);</font></li>
</ul>
<p>案例2：查询工资比公司平均工资高的员工的员工号，姓名和工资</p>
<ul>
<li><font color="#e96900" size="3">select employee_id, last_name, salary<br>from employees<br>where salary &gt; (<br>  select avg(salary)<br>  from employees<br>);</font></li>
</ul>
<p>案例3：查询各部门中工资比本部门中平均工资高的员工的员工号、姓名和工资</p>
<ul>
<li><font color="#e96900" size="3">select employee_id, last_name, salary<br>from employees e<br>left join (<br>  select department_id, avg(salary) avg_sal<br>  from employees<br>  group by department_id<br>) as temp on e.department_id &#x3D; temp.department_id<br>where e.salary &gt; temp.avg_sal;</font></li>
</ul>
<p>案例4：查询与姓名中包含字母‘u’的员工在相同部门的员工的员工号和姓名</p>
<ul>
<li><font color="#e96900" size="3">select employee_id, last_name<br>from employees<br>where department_id in (<br>  select distinct department_id<br>  from employees<br>  where last_name like &#39;%u%&#39;<br>);</font></li>
</ul>
<p>案例5：查询在部门的location_id为1700的部门工作的员工的员工号</p>
<ul>
<li><font color="#e96900" size="3">select employee_id<br>from employees<br>where department_id &#x3D; any(<br>  select distinct department_id<br>  from departments<br>  where location_id &#x3D; 1700<br>);</font></li>
</ul>
<p>案例6：查询管理者是K_ing的员工姓名和工资</p>
<ul>
<li><font color="#e96900" size="3">select last_name, salary<br>from employees<br>where manager_id in (<br>  select employee_id<br>  from employees<br>  where last_name &#x3D; &quot;K_ing&quot;<br>);</font></li>
</ul>
<p>案例7：查询工资最高的员工的姓名，要求first_name和last_name显示为一列，列明为 姓·名</p>
<ul>
<li><font color="#e96900" size="3">select concat(last_name, first_name), salary<br>from employees<br>where salary &#x3D; (<br>  select max(salary)<br>  from employees<br>);</font></li>
<li><font color="#e96900" size="3">select concat(last_name, first_name), salary<br>from employees<br>where salary &#x3D; (<br>  select salary<br>  from employees<br>  order by salary desc<br>  limit 1<br>);</font></li>
</ul>
</blockquote>
<h4 id="H、分页查询"><a href="#H、分页查询" class="headerlink" title="H、分页查询"></a>H、分页查询</h4><p>  非常具有应用场景，当要显示的数据，一页显示不全，就需要提交分页查询的sql请求。<br><strong>1、语法</strong></p>
<blockquote>
<p><font color="#e96900">select 查询列表<br>from 表1 别名1<br>【连接类型】join 表2 别名2 on 连接条件<br>【where 筛选条件】<br>【group by 分组字段】<br>【having 筛选条件】<br>【order by 排序字段 【asc|desc】】<br>limit offset, size;</font><br><strong>offset表示要显示条目的其实索引（起始索引从0开始）</strong><br><strong>size表示要显示的条目数</strong></p>
<blockquote>
<p><strong>特点：</strong></p>
<ul>
<li>limit语句放在查询语句的最后，是最后被执行的语句</li>
<li>分页公式：假设要显示的页数为 page，每页的条目数为 size<ul>
<li><code>select 查询列表 from 表 limit (page-1)*size, size;</code></li>
</ul>
</li>
</ul>
</blockquote>
</blockquote>
<p><strong>2、例子</strong></p>
<blockquote>
<p>案例1：查询前五条员工的信息</p>
<ul>
<li><font color="#e96900">select * from employees limit 0, 5;</font></li>
<li><font color="#e96900">select * from employees limit 5;</font>（当offset为0时，可以省略）</li>
</ul>
<p>案例2：查询第11条至第25条员工信息</p>
<ul>
<li><font color="#e96900">select * from employees limit 10, 15;</font></li>
</ul>
<p>案例3：查询有奖金的员工信息，并且工资较高的前10名显示</p>
<ul>
<li><font color="#e96900">select *<br>from employees<br>where commission_pct is not null<br>order by salary desc<br>limit 10;</font></li>
</ul>
</blockquote>
<h4 id="I、union联合查询"><a href="#I、union联合查询" class="headerlink" title="I、union联合查询"></a>I、union联合查询</h4><p>  联合查询是将多条查询语句的结果合并成一个结果。union会自动去掉重复的结果，可以使用union all达到不去重的效果。<br><strong>1、语法</strong></p>
<blockquote>
<p><font color="#e96900">查询语句1<br>union<br>查询语句2<br>union<br>查询语句3<br>……</font></p>
<blockquote>
<p><strong>应用场景：</strong></p>
<ul>
<li>要查询的结果可能来自于多个表，且多个表没有直接的连接关系，但查询的信息一致</li>
</ul>
<p><strong>特点：</strong></p>
<ol>
<li>要求多条查询语句的查询列数是一致的</li>
<li>要求多条查询语句的查询列表中每一列的类型和顺序最好一致，这样才有意义</li>
<li>union关键字默认是去重的，如果使用union all则可以包含重复项</li>
</ol>
</blockquote>
</blockquote>
<p><strong>2、例子</strong></p>
<blockquote>
<p>案例1：查询邮箱中部门编号&gt;90或邮箱中包含a的员工信息</p>
<ul>
<li><font color="#e96900">select * from employees where department_id &gt; 90<br>union<br>select * from employees where email like &quot;%a%&quot;;</font></li>
<li><font color="#e96900">select *<br>from employees<br>where department_id &gt; 90<br>or email like &#39;%a%&#39;;</font></li>
</ul>
</blockquote>
<hr>
<h3 id="四、DML-数据操纵语言"><a href="#四、DML-数据操纵语言" class="headerlink" title="四、DML 数据操纵语言"></a>四、DML 数据操纵语言</h3><p>  <strong>Data Manipulation Language</strong><br>  DML主要涉及到数据的插入（insert）、修改（update）和删除（delete）。</p>
<h4 id="A、插入语句"><a href="#A、插入语句" class="headerlink" title="A、插入语句"></a>A、插入语句</h4><p><strong>1、语法</strong></p>
<blockquote>
<ul>
<li>方式一：<ul>
<li>单行：<font color="#e96900" size="4">insert into 表名(列名, …) values(值1, …);</font></li>
<li>多行：<font color="#e96900" size="4">insert into 表名(列名, …)<br>  values(值1, …),<br>  (值2, …),<br>  ……<br>  (值n, …);</font></li>
</ul>
</li>
<li>方式二：<font color="#e96900" size="4">insert into 表名 set 列名1&#x3D;值, 列名2&#x3D;值, … ;</font></li>
</ul>
</blockquote>
<p><strong>2、案例特点</strong></p>
<blockquote>
<ul>
<li>插入的值的类型要与列的类型一致或兼容<blockquote>
<ul>
<li><font color="#e96900">insert into beauty(id, NAME, sex, borndate, phone, photo, boyfriend_id)<br>values(13, &#39;唐老鸭&#39;, &#39;女&#39;, &#39;1990-4-23&#39;, &#39;13676542378&#39;, null, 2);</font></li>
<li><font color="#e96900">insert into beauty<br>set id&#x3D;13, name&#x3D;&#39;唐老鸭&#39;, sex&#x3D;&#39;女&#39;, borndate&#39;1990-4-23&#39;, phone&#x3D;&#39;13676542378&#39;, photo&#x3D;null, boyfriend_id&#x3D;2;</font></li>
</ul>
</blockquote>
</li>
<li>不可以为null的列必须插入值，可以为null的列可以插入null值，或直接不插入值<blockquote>
<ul>
<li><font color="#e96900">insert into beauty(id, name, sex, borndate, phone, photo, boyfriend_id)<br>values(13, &#39;唐老鸭&#39;, &#39;女&#39;, &#39;1990-4-23&#39;, &#39;13676542378&#39;, null, 2);</font></li>
<li><font color="#e96900">insert into beauty(id, name, sex, borndate, phone, boyfriend_id)<br>values(13, &#39;唐老鸭&#39;, &#39;女&#39;, &#39;1990-4-23&#39;, &#39;13676542378&#39;, 9);</font></li>
<li><font color="#e96900">insert into beauty(id, name, sex, phone)<br>values(14, &#39;米老鼠&#39;, &#39;女&#39;, &#39;12398776543&#39;);</font></li>
<li><font color="#e96900">insert into beauty<br>set id&#x3D;14, name&#x3D;&#39;米老鼠&#39;, sex&#x3D;&#39;女&#39;, phone&#x3D;&#39;12398776543&#39;;</font></li>
</ul>
</blockquote>
</li>
<li>列的顺序可以调换，但是后面的值需要一一对应</li>
<li>列数和值的个数必须要一致</li>
<li>可以省略列名，省略后就是默认所有列，而且列的顺序和表中列的顺序一致<blockquote>
<ul>
<li><font color="#e96900">insert into beauty<br>values(15, &#39;张飞&#39;, &#39;男&#39;, &#39;1990-5-12&#39;, &#39;12387656789&#39;, null, null);</font></li>
</ul>
</blockquote>
</li>
</ul>
</blockquote>
<p><strong>3、插入方式对比</strong></p>
<blockquote>
<ul>
<li>values的方式支持多行插入，set的方式不支持多行插入<blockquote>
<ul>
<li><font color="#e96900">insert into 表名(列明, …)<br>values(值1, …),<br>values(值2, …),<br>……<br>values(值n, …);</font></li>
<li><font color="#e96900">insert into beauty<br>values(16, &#39;张飞&#39;, &#39;男&#39;, &#39;1990-5-12&#39;, &#39;12387656789&#39;, null, null),<br>(17, &#39;张飞&#39;, &#39;男&#39;, &#39;1990-5-12&#39;, &#39;12387656789&#39;, null, null),<br>(18, &#39;张飞&#39;, &#39;男&#39;, &#39;1990-5-12&#39;, &#39;12387656789&#39;, null, null);</font></li>
</ul>
</blockquote>
</li>
<li>values的方式支持子查询，set的方式不支持子查询<blockquote>
<ul>
<li><font color="#e96900">insert into beauty(id, name, sex, phone)<br>select 19, &#39;貂蝉&#39;, &#39;女&#39;, &#39;12345687654&#39;;</font></li>
<li><font color="#e96900">insert into beauty(id, name, sex, phone)<br>select id+20, boyname, &#39;男&#39;, &#39;112&#39;<br>from boys where id &lt; 3;</font></li>
</ul>
</blockquote>
</li>
</ul>
</blockquote>
<h4 id="B、修改语句"><a href="#B、修改语句" class="headerlink" title="B、修改语句"></a>B、修改语句</h4><p><strong>1、修改单表记录</strong></p>
<blockquote>
<ul>
<li><strong>语法：</strong><blockquote>
<p><font color="#e96900" size="4">update 表名<br>set 列1&#x3D;新值, 列2&#x3D;新值, …<br>where 筛选条件;</font></p>
</blockquote>
</li>
<li>案例1：修改beauty表中id大于等于13的记录的电话为12345678909<blockquote>
<ul>
<li><font color="#e96900">update beauty<br>set phone&#x3D;&#39;12345678909&#39;<br>where id &gt;&#x3D; 13;</font></li>
</ul>
</blockquote>
</li>
</ul>
</blockquote>
<p><strong>2、修改多表记录【补充】</strong></p>
<blockquote>
<ul>
<li><strong>语法：</strong><blockquote>
<ul>
<li>sql92语法：<br><font color="#e96900" size="4">update 表1 别名, 表2 别名<br>set 列1&#x3D;新值, 列2&#x3D;新值, …<br>where 连接条件<br>and 筛选条件;</font></li>
<li>sql99语法：<br><font color="#e96900" size="4">update 表1 别名<br>inner|left|right| join 表2 别名<br>on 连接条件<br>set 列1&#x3D;新值, 列2&#x3D;新值, …<br>where 筛选条件;</font></li>
</ul>
</blockquote>
</li>
<li>案例1：修改张无忌的女朋友的手机号为114<blockquote>
<ul>
<li><font color="#e96900">update boys bo<br>inner join beauty b on bo.id &#x3D; b.boyfriend_id<br>set b.phone &#x3D; &#39;114&#39;<br>where bo.boyName &#x3D; &quot;张无忌&quot;;</font></li>
</ul>
</blockquote>
</li>
<li>案例2：修改没有男盆友的女神的男盆友编号都为2号<blockquote>
<ul>
<li><font color="#e96900">update boys bo<br>right join beauty b on bo.id &#x3D; b.boyfriend_id<br>set b.boyfriend_id &#x3D; 2<br>where bo.id is null;</font></li>
</ul>
</blockquote>
</li>
</ul>
</blockquote>
<h4 id="C、删除语句"><a href="#C、删除语句" class="headerlink" title="C、删除语句"></a>C、删除语句</h4><p><strong>1、语法</strong></p>
<blockquote>
<ul>
<li>方式一：delete（可按照筛选进行删除）<ul>
<li>单表删除：<font color="#e96900" size="4">delete from 表名 where 筛选条件;</font></li>
<li>多表删除：<ul>
<li>sql92：<br>  <font color="#e96900" size="4">delete 别名1【,别名2】<br>  from 表1 别名1, 表2 别名2<br>  where 连接条件<br>  and 筛选条件;</font></li>
<li>sql99：<br>  <font color="#e96900" size="4">delete 别名1【,别名2】<br>  from 表1 别名1<br>  inner|left|right join 表2 别名2 on 连接条件<br>  where 筛选条件;</font></li>
</ul>
</li>
</ul>
</li>
<li>方式二：truncate（不能筛选，也就是不能加where，只能整表删除）<ul>
<li><font color="#e96900" size="4">truncate table 表名;</font></li>
</ul>
</li>
</ul>
</blockquote>
<p><strong>2、案例</strong></p>
<blockquote>
<p>案例1：删除手机号以9结尾的女神信息</p>
<ul>
<li><font color="#e96900">delete from beauty where phone like &#39;%9&#39;;</font></li>
</ul>
<p>案例2：删除张无忌的女朋友的信息</p>
<ul>
<li><font color="#e96900">delete b<br>from beauty b<br>inner join boys bo on b.boyfriend_id &#x3D; bo.id<br>where bo.boyName &#x3D; &quot;张无忌&quot;;</font></li>
</ul>
<p>案例3：删除黄晓明的信息以及他女朋友的信息</p>
<ul>
<li><font color="#e96900">delete b, bo<br>from beauty b<br>inner join boys bo on b.boyfriend_id &#x3D; bo.id<br>where bo.boyName &#x3D; &quot;黄晓明&quot;;</font></li>
</ul>
<p>案例4：truncate清空数据</p>
<ul>
<li><font color="#e96900">truncate table boys;</font></li>
</ul>
</blockquote>
<p><strong>3、delete 和 truncate 区别</strong></p>
<ul>
<li>delete 可以加where条件，truncate 不能加where条件</li>
<li>truncate 可以理解为清空全表，效率高一丢丢</li>
<li>假如要删除的表中有自增长列，如果用delete删除后，再插入数据，自增长列的值从断点开始；而truncate删除后，在插入数据，自增长列的值从1开始</li>
<li>truncate 删除没有返回值，而delete删除有返回值（受影响的行数）</li>
<li>truncate 删除后不能回滚，delete删除后可以回滚</li>
</ul>
<hr>
<h3 id="五、DDL-数据库模式定义语言"><a href="#五、DDL-数据库模式定义语言" class="headerlink" title="五、DDL 数据库模式定义语言"></a>五、DDL 数据库模式定义语言</h3><p>  <strong>Data Definition Language</strong>，与DML语言不同，DML语言是在操作库中数据表中的数据，而DDL语言是操作库和表的结构。DML对应增删改（insert，delete，update）数据，DDL对应创建删除修改（create，drop，alter）库和表的结构。<code>IF EXISTS</code>或<code>IF NOT EXISTS</code>只能用在库或表的创建和删除时，新建列和删除列时不能用。</p>
<h4 id="A、库和表的管理"><a href="#A、库和表的管理" class="headerlink" title="A、库和表的管理"></a>A、库和表的管理</h4><p><strong>1、库的管理（创建create、修改alter、删除drop）</strong></p>
<ul>
<li><p>库的创建：<font color="e96900" size="4">create database [if not exists] 库名;</font></p>
<blockquote>
<p>案例1：创建Books库</p>
<ul>
<li><font color="#e96900">CREATE DATABASE Books;</font></li>
</ul>
<p>案例2：创建Books库，但是创建前先判断是否存在</p>
<ul>
<li><font color="#e96900">create database if not exists Books;</font></li>
</ul>
</blockquote>
</li>
<li><p>库的修改：<font color="e96900" size="4">alter database 库名 修改操作;</font><br>  一般来说数据库不修改。<font color="#e96900">rename database books to 新库名;</font>（已废弃，不够安全，有丢失数据的风险）</p>
<blockquote>
<p>案例1：更改库的字符集</p>
<ul>
<li><font color="#e96900">alter database books character set gbk;</font></li>
</ul>
</blockquote>
</li>
<li><p>库的删除：<font color="e96900" size="4">drop database [if exists] 库名;</font></p>
<blockquote>
<p>案例1：删除库</p>
<ul>
<li><font color="#e96900">drop database if exists books;</font></li>
</ul>
</blockquote>
</li>
</ul>
<p><strong>2、表的管理（创建create、修改alter、删除drop）</strong></p>
<ul>
<li><p>表的创建 ★</p>
<blockquote>
<p>语法：</p>
<ul>
<li><font color="#e96900" size="3">create table [if not exists] 表名(<br>  列名 列的类型[(长度)] [约束],<br>  列名 列的类型[(长度)] [约束],<br>  列名 列的类型[(长度)] [约束],<br>  ……<br>  列名 列的类型[(长度)] [约束]<br>);</font></li>
</ul>
<p>案例1：创建表 Book</p>
<ul>
<li><font color="#e96900">create table book(<br>  id INT,<br>  bName VARCHAR(20),<br>  price DOUBLE,<br>  authorID INT,<br>  publishDate DATETIME<br>);</font></li>
</ul>
<p>案例2：创建表 Author</p>
<ul>
<li><font color="#e96900">create table if not exists author(<br>  id INT,<br>  au_name VARCHAR(20),<br>  nation VARCHAR(10)<br>);</font></li>
</ul>
</blockquote>
</li>
<li><p>表的修改</p>
<blockquote>
<ul>
<li>修改列名</li>
<li>修改列的类型或约束</li>
<li>添加新的列</li>
<li>删除列</li>
<li>修改表名</li>
</ul>
<p>语法：</p>
<ul>
<li><font color="e96900" size="3">alter table 表名 add | drop | modify | change column 列名 [列类型 约束];</font></li>
</ul>
<p>案例：</p>
<ul>
<li><code>ALTER TABLE book CHANGE COLUMN publishdate pubDate DATETIME;</code></li>
<li><code>ALTER TABLE book MODIFY COLUMN pubdate TIMESTAMP;</code></li>
<li><code>ALTER TABLE author ADD COLUMN annual DOUBLE;</code></li>
<li><code>ALTER TABLE author DROP COLUMN annual; </code></li>
<li><code>ALTER TABLE author RENAME TO book_author;</code></li>
</ul>
</blockquote>
</li>
<li><p>表的删除</p>
<blockquote>
<p>语法：<font color="#e96900" size="3">drop table [if exists] 表名</font><br><code>drop table if exists book_author;</code></p>
</blockquote>
</li>
<li><p>表的复制</p>
<blockquote>
<ul>
<li>仅复制表的结构<blockquote>
<p><font color="#e96900">CREATE TABLE copy1_author LIKE author;</font></p>
</blockquote>
</li>
<li>复制表的结构和全部数据<blockquote>
<p><font color="#e96900">CREATE TABLE copy2_author<br>SELECT * FROM author;</font></p>
</blockquote>
</li>
<li>复制表的结构和部分数据<blockquote>
<p><font color="#e96900">CREATE TABLE copy3_author<br>SELECT id, au_name, nation<br>FROM author<br>where nation &#x3D; &quot;中国&quot;;</font></p>
</blockquote>
</li>
<li>复制部分表结构（仅仅复制某些字段）<blockquote>
<p><font color="#e96900">CREATE TABLE copy4_author<br>select id, au_name<br>from author<br>where 0;</font></p>
</blockquote>
</li>
</ul>
</blockquote>
</li>
</ul>
<p><strong>3、建库建表的通常写法：</strong></p>
<ul>
<li><font color="#e96900">DROP DATABASE IF EXISTS 库名;<br>CREATE DATABASE 库名;</font></li>
<li><font color="#e96900">DROP TABLE IF EXISTS 表名;<br>CREATE TABLE 表名(…);</font></li>
</ul>
<h4 id="B、常见数据类型介绍"><a href="#B、常见数据类型介绍" class="headerlink" title="B、常见数据类型介绍"></a>B、常见数据类型介绍</h4><ul>
<li>数值型：<ul>
<li>整型 ★</li>
<li>小数：<ul>
<li>定点数</li>
<li>浮点数 ★</li>
</ul>
</li>
</ul>
</li>
<li>字符型：★<ul>
<li>较短的文本：char、varchar</li>
<li>较长的文本：text、blob（二进制数据，比如图片）</li>
</ul>
</li>
<li>日期型 ★</li>
</ul>
<p><strong>1、整型</strong><br>  <strong>tinyint、smallint、mediumint、int&#x2F;integer、bigint</strong></p>
<blockquote>
<table>
<thead>
<tr>
<th>整数类型</th>
<th>字节</th>
<th>范围</th>
</tr>
</thead>
<tbody><tr>
<td>Tinyint</td>
<td>1</td>
<td>有符号：-128 ~ 127<br>无符号：0 ~ 255</td>
</tr>
<tr>
<td>Samllint</td>
<td>2</td>
<td>有符号：-(2)<sup>15</sup> ~ 2<sup>15</sup>-1<br>无符号：0 ~ 2<sup>16</sup>-1</td>
</tr>
<tr>
<td>Mediumint</td>
<td>3</td>
<td>有符号：-(2)<sup>23</sup> ~ 2<sup>23</sup>-1<br>无符号：0 ~ 2<sup>24</sup>-1</td>
</tr>
<tr>
<td>Int、Integer</td>
<td>4</td>
<td>有符号：-(2)<sup>31</sup> ~ 2<sup>31</sup>-1<br>无符号：0 ~ 2<sup>32</sup>-1</td>
</tr>
<tr>
<td>Bigint</td>
<td>8</td>
<td>有符号：-(2)<sup>63</sup> ~ 2<sup>63</sup>-1<br>无符号：0 ~ 2<sup>64</sup>-1</td>
</tr>
</tbody></table>
<p><strong>特点：</strong></p>
<ul>
<li><p>如果不设置无符号还是有符号，则默认是有符号的。如果想设置无符号，需要添加<strong>unsigned</strong>关键字。</p>
</li>
<li><p>如果插入的数值超出了该整数类型的数值范围，会报out of range异常，并且会<strong>插入临界值</strong>。</p>
</li>
<li><p>如果不设置长度，会有默认的长度。该长度代表了显示的最大宽度，如果不够会用0在左侧填充，但必须搭配<strong>zerofill</strong>关键字一起使用才有效果。使用zerofill后，就<strong>自动变为了无符号的整数类型</strong>。</p>
</li>
<li><p><font color="#e96900">drop table if exists tab_int;<br>create table tab_int(<br>  c1 INT,<br>  c2 INT(7) ZEROFILL,<br>  c3 INT UNSIGNED,<br>  c4 INT(8) UNSIGNED<br>);</font></p>
</li>
</ul>
</blockquote>
<p><strong>2、小数</strong></p>
<blockquote>
<table>
<thead>
<tr>
<th>浮点数类型</th>
<th>字节</th>
<th>范围</th>
</tr>
</thead>
<tbody><tr>
<td>float</td>
<td>4</td>
<td>±1.75494351E-38 ~ ±3.402823466E+38</td>
</tr>
<tr>
<td>double</td>
<td>8</td>
<td>±2.2250738585072014E-308 ~ ±1.7976931348623157E+308</td>
</tr>
</tbody></table>
<table>
<thead>
<tr>
<th>定点数</th>
<th>字节</th>
<th>范围</th>
</tr>
</thead>
<tbody><tr>
<td>dec(M, D)<br>decimal(M, D)</td>
<td>M+2</td>
<td>最大取值范围与double相同，给定decimal的有效取值范围由M和D决定</td>
</tr>
</tbody></table>
<ul>
<li>浮点型 float(M, D)、double(M, D)</li>
<li>定点型 dec(M, D)、decimal(M, D)</li>
</ul>
<p><strong>特点：</strong></p>
<ul>
<li><font color="#0088ee"><strong>M</strong> 表示整部位 + 小数部位的长度。</font></li>
<li><font color="#0088ee"><strong>D</strong> 表示小数部位的长度。</font></li>
<li>如果超过范围，则插入临界值。</li>
<li><font color="#0088ee"><strong>M</strong> 和 <strong>D</strong>都可以省略。如果是decimal，则M默认为10，D默认为0；如果是float和double，则会根据插入的数值的精度来决定精度。</font></li>
<li>定点型的精度较高，如果要求插入数值的精度较高如货币运算等则考虑使用。</li>
<li><font color="#e96900">drop table if exists tab_float;<br>create table tab_float(<br>  f1 FLOAT(5, 2),<br>  f2 DOUBLE(5, 2),<br>  f3 DECIMAL(5, 2)<br>);</font></li>
<li><code>insert into tab_float values(123.45, 123.45, 123.45);</code> 执行成功</li>
<li><code>insert into tab_float values(123.456, 123.456, 123.456);</code> 四舍五入成123.46</li>
<li><code>insert into tab_float values(123.4, 123.4, 123.4);</code> 结果为123.40</li>
<li><code>insert into tab_float values(1523.4, 1523.4, 1523.4);</code> 如果能插入，插入的值为999.99</li>
</ul>
</blockquote>
<p><strong>3、字符型</strong></p>
<ul>
<li>较短的文本：char、varchar</li>
<li>较长的文本：text、blob（较大二进制）</li>
<li>binary和varbinary用于保存较短的二进制</li>
<li>enum用于保存枚举</li>
<li>set用于保存集合<blockquote>
<table>
<thead>
<tr>
<th>字符串类型</th>
<th>最多字符数</th>
<th>描述及存储需求</th>
</tr>
</thead>
<tbody><tr>
<td>char(M)</td>
<td>M</td>
<td>M为0~255之间的整数</td>
</tr>
<tr>
<td>varchar(M)</td>
<td>M</td>
<td>M为0~65535之间的整数</td>
</tr>
<tr>
<td>说明：</td>
<td></td>
<td></td>
</tr>
</tbody></table>
<ul>
<li><strong>binary和varbinary类型</strong>类似于char和varchar类型，不同的是它们包含二进制字符串而不包含非二进制字符串。</li>
<li><strong>bit(M)表示位类型</strong>，占 1 ~ 8 个字节，范围为 bit(1) ~ bit(8)。</li>
<li><strong>enum类型</strong>，又称为枚举类型。要求插入的值必须为列表中指定的值之一。如果列表成员为1 ~ 255，则需要1个字节存储；如果列表成员为255 ~ 65535，则需要2个字节存储；最多需要65535个成员。</li>
<li><font color="#e96900">drop table if exists tab_char;<br>create table tab_char(<br>  c1 ENUM(&#39;a&#39;, &#39;b&#39;, &#39;c&#39;)<br>);</font></li>
<li><code>insert into tab_char values(&#39;a&#39;);</code> 成功插入</li>
<li><code>insert into tab_char values(&#39;m&#39;);</code> 报错</li>
<li><strong>set类型</strong>，和enum类型类似，里面可以保存0 ~ 64个成员。和enum类型最大的区别是：set类型一次可以选取多个成员，而enum只能选取一个。根据成员个数的不同，存储所占的字节也不同。成员数1 ~ 8，字节数为1；成员数9 ~ 16，字节数为2；成员数17 ~ 24，字节数为3；成员数25 ~ 32，字节数为4；成员数33 ~ 64，字节数为8；</li>
<li><font color="#e96900">drop table if exists tab_char;<br>create table tab_char(<br>  s1 SET(&#39;a&#39;, &#39;b&#39;, &#39;c&#39;, &#39;d&#39;)<br>);</font></li>
<li><code>insert into tab_char values(&#39;a&#39;);</code> 成功插入</li>
<li><code>insert into tab_char values(&#39;A,B&#39;);</code> 成功插入</li>
<li><code>insert into tab_char values(&#39;a,b,d&#39;);</code> 成功插入</li>
</ul>
<p><strong>char和varchar的特点：</strong></p>
<ul>
<li>语法相同char(M)、varchar(M)，其中M代表的含义也相同，表示最多字符数。</li>
<li>char(M) 表示固定长度的字符，M可以省略，默认为1；varchar(M) 表示可变长度的字符，M不可以省略。</li>
<li>char 比较耗费存储空间，varchar 比较节省存储空间。</li>
<li>char 的效率高，varchar 的效率低。</li>
</ul>
</blockquote>
</li>
</ul>
<p><strong>4、日期型</strong></p>
<blockquote>
<table>
<thead>
<tr>
<th>日期和时间类型</th>
<th>字节</th>
<th>最小值</th>
<th>最大值</th>
</tr>
</thead>
<tbody><tr>
<td>date</td>
<td>4</td>
<td>1000-01-01</td>
<td>9999-12-31</td>
</tr>
<tr>
<td>time</td>
<td>3</td>
<td>-838:59:59</td>
<td>838:59:59</td>
</tr>
<tr>
<td>year</td>
<td>1</td>
<td>1901</td>
<td>2155</td>
</tr>
<tr>
<td>datetime</td>
<td>8</td>
<td>1000-01-01 00:00:00</td>
<td>9999-12-31 23:59:59</td>
</tr>
<tr>
<td>timestamp</td>
<td>4</td>
<td>19700101080001</td>
<td>2038年的某个时刻</td>
</tr>
<tr>
<td>说明：</td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody></table>
<ul>
<li>date值保存日期，time只保存时间，year只保存年</li>
<li>datetime保存日期 + 时间</li>
<li>timestamp保存日期 + 时间</li>
<li>timestamp支持的时间范围较小，取值范围：19700101080001 —— 2038年的某个时刻</li>
<li>datetime的取值范围是：1000-01-01 00:00:00 —— 9999-12-31 23:59:59</li>
<li><strong>timestamp和实际时区有关，更能反映实际的日期</strong>，而datetime则只能反映出插入时的当地时区</li>
<li>timestamp的属性受MySql版本和SQLMode的影响很大</li>
<li><font color="#e96900">drop table if exists tab_date;<br>create table tab_date(<br>  t1 DATETIME,<br>  t2 TIMESTAMP<br>);</font></li>
<li><code>insert into tab_date values(now(), now());</code></li>
</ul>
</blockquote>
<h4 id="C、常见约束"><a href="#C、常见约束" class="headerlink" title="C、常见约束"></a>C、常见约束</h4><p>  约束是一种限制，用于限制表中的数据，为了保证表中数据的准确性和可靠性。</p>
<ul>
<li>分类：（六大约束）<ul>
<li><strong>NOT NULL</strong>（非空，用于保证该字段的值不能为空）</li>
<li><strong>DEFAULT</strong>（默认，用于保证该字段有默认值）</li>
<li><strong>PRIMARY KEY</strong>（主键，用于保证该字段的值具有唯一性，并且非空）</li>
<li><strong>UNIQUE</strong>（唯一，用于保证该字段的值具有唯一性，可以为空）</li>
<li><strong>CHECK</strong>（检查约束，【mysql中不支持】，用于保证该字段满足一定条件）</li>
<li><strong>FOREIGN KEY</strong>（外键，用于限制两个表的关系，用于保证该字段的值必须来自于主表的关联列的值。在从表中添加外键约束，用于引用主表中某列的值）</li>
</ul>
</li>
<li>添加约束的时机：<ul>
<li>创建表时</li>
<li>修改表时</li>
</ul>
</li>
<li>约束的添加分类：<ul>
<li>列级约束：六大约束语法上都支持列级约束，但<strong>外键约束和检查约束加在列级约束上没有效果</strong></li>
<li>表级约束：除了非空和默认约束外，其他约束都支持，但不一定都有效果，比如check可以加，但没效果</li>
</ul>
</li>
<li>主键和唯一的对比：<ul>
<li>主键保证了唯一性，且不能为空。一个表中最多只能有一个主键。允许多个字段组合成一个主键，但是要满足唯一性要求。</li>
<li>唯一性约束也保证了唯一性，但是可以为空，但是只能有一个记录的值为空，多个记录为空那不就重复了吗。一个表中可以有多个唯一键。允许多个字段组合成一个唯一键，但是得满足唯一性要求。</li>
</ul>
</li>
<li>外键说明：<ul>
<li>要求在从表设置外键关系</li>
<li>从表的外键列的类型和主表的关联列的类型要求一直或兼容，名称无要求</li>
<li><strong>主表的关联列必须是一个key（一般是主键或唯一）</strong></li>
<li>插入数据时，先插入主表，再插入从表；删除数据时，先删除从表，再删除主表</li>
</ul>
</li>
</ul>
<p><strong>1、列级约束（创建表时）</strong><br>  直接在字段名和字段类型后面追加 约束类型即可。只支持：default、not null、primary key、unique</p>
<blockquote>
<p>案例：</p>
<ul>
<li><font color="#e96900">drop database if exists students;<br>create database students;<br>use students;<br>drop table if exists major;<br>create table major(<br>  id INT primary key,<br>  majorName VARCHAR(20) not null<br>);</font></li>
<li><font color="#e96900">use students;<br>drop table if exists stuinfo;<br>create table stuinfo(<br>  id INT primary key,<br>  stuName VARCHAR(20) not null,<br>  gender CHAR(1) check(gender&#x3D;&#39;男&#39; or gender&#x3D;&#39;女&#39;),<br>  seat INT unique,<br>  age INT default 18,<br>  majorId INT foreign key references major(id)<br>);</font></li>
<li>使用<code>show index from stuinfo;</code>可以查看该表上的索引，包括主键、外键、唯一键。主键(primary key)和唯一键(unique)会自动生成索引，主键会生成主键索引，整个表的数据是按照主键索引生成的树结构来组织的，唯一键会生成唯一索引，唯一索引不同于普通索引。这里使用<code>show index from stuinfo;</code>只能看到主键和唯一键，不能看到外键，因为外键约束加在列级约束上没有效果。</li>
</ul>
</blockquote>
<p><strong>2、表级约束（创建表时）</strong><br>  在各个字段声明完成后的最下面，加上表级约束即可。语法：<code>【constraint 约束名】 约束类型(字段名)</code></p>
<blockquote>
<p>案例：</p>
<ul>
<li><font color="#e96900">drop table if exists stuinfo;<br>create table stuinfo(<br>  id INT,<br>  stuName VARCHAR(20),<br>  gender CHAR(1),<br>  seat INT,<br>  age INT,<br>  majorId INT,<br>  CONSTRAINT pk PRIMARY KEY(id),<br>  CONSTRAINT uq UNIQUE(seat),<br>  CONSTRAINT ck CHECK(gender in (&#39;男&#39;, &#39;女&#39;)),<br>  CONSTRAINT fk_stuinfo_major FOREIGN KEY(majorId) references major(id)<br>);</font></li>
<li>这里使用<code>show index from stuinfo;</code>可以查看该表上的索引，包括主键、外键、唯一键。主键的名称即使我们为其改名为”pk”也没有效果，主键名称就叫”PRIMARY”（MySql中的奇怪规则）。</li>
</ul>
</blockquote>
<p><strong>3、一般的约束写法</strong><br>  主键约束、非空约束、唯一约束、默认约束可以作为列级约束直接追加到每列申明的后面，外键约束使用表级约束的方式添加。而检查约束在mysql中只支持语法，也就是不报错，但是没有任何效果。</p>
<blockquote>
<p><font color="#e96900">create table if not exists stuinfo(<br>  id INT primary key,<br>  stuName VARCHAR(20) not null,<br>  gender CHAR(1),<br>  seat INT unique,<br>  age int default 18,<br>  majorId INT,<br>  CONSTRAINT fk_stuinfo_major FOREIGN KEY(majorId) REFERENCES major(id)<br>);</font></p>
</blockquote>
<p><strong>4、修改表时添加约束</strong></p>
<ul>
<li>添加列级约束<ul>
<li><code>alter table 表名 modify column 字段名 字段类型 列级约束;</code></li>
</ul>
</li>
<li>添加表级约束<ul>
<li><code>alter table 表名 add [constraint 自定义约束名] 表级类型(字段名) [外键的引用];</code></li>
</ul>
</li>
</ul>
<blockquote>
<p>建表：</p>
<ul>
<li><font color="#e96900">drop table if exists stuinfo;<br>create table stuinfo(<br>  id INT,<br>  stuName VARCHAR(20),<br>  gender CHAR(1),<br>  seat INT,<br>  age INT,<br>  majorID INT<br>);</font></li>
</ul>
<p>添加非空约束：</p>
<ul>
<li><code>ALTER TABLE stuinfo MODIFY COLUMN stuName VARCHAR(20) NOT NULL;</code> 列级约束</li>
</ul>
<p>添加默认约束：</p>
<ul>
<li><code>ALTER TABLE stuinfo MODIFY COLUMN age INT DEFAULT 18;</code> 列级约束</li>
</ul>
<p>添加主键：</p>
<ul>
<li><code>ALTER TABLE stuinfo MODIFY COLUMN id INT PRIMARY KEY;</code> 列级约束</li>
<li><code>ALTER TABLE stuinfo ADD PRIMARY KEY(id);</code> 表级约束</li>
</ul>
<p>添加唯一约束：</p>
<ul>
<li><code>ALTER TABLE stuinfo MODIFY COLUMN seat INT UNIQUE;</code> 列级约束</li>
<li><code>ALTER TABLE stuinfo ADD UNIQUE(seat);</code> 表级约束</li>
</ul>
<p>添加外键：</p>
<ul>
<li><code>ALTER TABLE stuinfo ADD FOREIGN KEY(majorId) REFERENCES major(id);</code> 表级约束</li>
<li><code>ALTER TABLE stuinfo ADD CONSTRAINT fk_stuinfo_major FOREIGN KEY(majorId) REFERENCES major(id);</code> 表级约束</li>
</ul>
</blockquote>
<p><strong>4、修改表时删除约束</strong></p>
<blockquote>
<p>删除非空约束</p>
<ul>
<li><code>ALTER TABLE stuinfo MODIFY COLUMN stuname VARCHAR(20) NULL;</code></li>
</ul>
<p>删除默认约束</p>
<ul>
<li><code>ALTER TABLE stuinfo MODIFY COLUMN age INT;</code></li>
</ul>
<p>删除主键</p>
<ul>
<li><code>ALTER TABLE stuinfo MODIFY COLUMN id INT;</code></li>
<li><code>ALTER TABLE stuinfo DROP PRIMARY KEY;</code></li>
</ul>
<p>删除唯一约束</p>
<ul>
<li><code>ALTER TABLE stuinfo DROP INDEX seat;</code></li>
</ul>
<p>删除外键</p>
<ul>
<li><code>ALTER TABLE sutinfo DROP FOREIGN KEY fk_stuinfo_major;</code></li>
</ul>
</blockquote>
<h4 id="D、自增长列（标识列）"><a href="#D、自增长列（标识列）" class="headerlink" title="D、自增长列（标识列）"></a>D、自增长列（标识列）</h4><p>  标识列又称为自增长列，可以不用手动地插入值，系统提供默认的序列值。<br><strong>1、创建表时设置标识列</strong></p>
<blockquote>
<ul>
<li><font color="#e96900">drop table if exists tab_identity;<br>create table tab_identity(<br>  id INT PRIMARY KEY AUTO_INCREMENT,<br>  name VARCHAR(20)<br>);</font></li>
<li><code>INSERT INTO tab_identity VALUES(NULL, &#39;Tom&#39;);</code> id字段的值自动插入1</li>
<li><code>INSERT INTO tab_identity VALUES(NULL, &#39;john&#39;);</code> id字段的值自动增长到2</li>
<li><code>INSERT INTO tab_identity(name) VALUES(&#39;jerry&#39;);</code>id字段的值自动增长到3</li>
<li><code>INSERT INTO tab_identity SET name=&#39;marry&#39;;</code>id字段的值自动增长到4</li>
<li>使用<code>delete from tab_identity;</code>后再次添加数据时，id字段的值自动从断点处开始增长</li>
<li>使用<code>truncate table tab_identity;</code>后再次添加数据时，id字段的值又重新从1开始自增</li>
</ul>
</blockquote>
<p><strong>2、自增长的系统参数设置</strong></p>
<blockquote>
<ul>
<li><font color="#e96900">show variables like &#39;%auto_increment%&#39;;</font></li>
<li><table>
<thead>
<tr>
<th>Variable_name</th>
<th>Value</th>
</tr>
</thead>
<tbody><tr>
<td>auto_increment_increment</td>
<td>1</td>
</tr>
<tr>
<td>auto_increment_offset</td>
<td>1</td>
</tr>
</tbody></table>
</li>
<li><strong>auto_increment_offset</strong> 表示起始值是 1</li>
<li><strong>auto_increment_increment</strong> 表示每次增长的步长是 1</li>
<li>MySql中不支持对 auto_increment_offset 的更改，即使改了也没效果<ul>
<li>但是你可以在插入值的时候指定一个值，之后的插入就会以你指定的值开始增长</li>
<li><code>insert into tab_identity values(10, &#39;jack&#39;);</code> id字段的值直接就是10了</li>
<li><code>insert into tab_identity values(null, &#39;rose&#39;);</code> id字段的值自动增长到11</li>
</ul>
</li>
<li>auto_increment_increment 在MySql中是支持更改的，并且改了确确实实有效果<ul>
<li><code>SET auto_increment_increment = 3;</code></li>
</ul>
</li>
</ul>
</blockquote>
<p><strong>3、使用特点</strong></p>
<ul>
<li>标识列不一定要和主键搭配，但是要求标识列一定是一个key（比如primary key, unique, foreign key）</li>
<li>一个表中最多只能有一个标识列</li>
<li>标识列的类型只能是数值型（比如int，float，double），一般是 int</li>
<li>标识列可以通过 <code>SET auto_increment_increment = 3;</code> 设置步长；也可以通过手动插入值的方式设置起始值</li>
<li>可以在修改表的时候设置标识列，遵循修改表的语法。<code>ALTER TABLE tab_identity MODIFY COLUMN id INT PRIMARY KEY AUTO_INCREMENT;</code></li>
<li>可以在修改表的时候删除标识列，遵循修改表的语法。<code>ALTER TABLE tab_identity MODIFY COLUMN id INT;</code></li>
</ul>
<hr>
<h3 id="六、TCL-事务控制语言"><a href="#六、TCL-事务控制语言" class="headerlink" title="六、TCL 事务控制语言"></a>六、TCL 事务控制语言</h3><p>  <strong>Transaction Control Language</strong><br>  事务：一个或一组sql语句组成一个执行单元，这个执行单元作为一个不可分割的整体，要么全部执行，要么全部不执行。如果这个执行单元中某条SQL语句执行失败或产生错误，整个单元将会回滚，所有受到影响的数据将会返回到该事务开始以前的状态；如果单元中的的所有sql语句均执行成功，则事务被顺利执行。<br>  在mysql中，数据用各种不同的技术存储在文件或内存中。通过 <code>show engines;</code> 可以查看mysql支持的存储引擎。在mysql中用的最多的存储引擎有：innodb、myisam、memory等。其中<strong>innodb支持事务，而myisam、memory等不支持事务</strong>。</p>
<h4 id="A、事务的ACID属性"><a href="#A、事务的ACID属性" class="headerlink" title="A、事务的ACID属性"></a>A、事务的ACID属性</h4><blockquote>
<p>事务的ACID属性：</p>
<ul>
<li>原子性（Atomicity）<ul>
<li>原子性是指事务是一个不可分割的工作单位，事务中的操作要么都发生，要么都不发生。</li>
</ul>
</li>
<li>一致性（Consistency）<ul>
<li>事务必须使数据库从一个一致性状态变换到另一个一致性状态。</li>
</ul>
</li>
<li>隔离性（Isolation）<ul>
<li>事务的隔离性是指一个事务的执行不能被其他事务所干扰，即一个事务内部的操作及使用的数据对并发的其他事务来说是隔离的，并发执行的各个事务之间不能相互干扰。</li>
</ul>
</li>
<li>持久性（Durability）<ul>
<li>持久性是指一个事务一旦被提交，它对数据库中数据的改变就是永久性的，接下来的其他操作和数据库故障不应该对其有任何影响。</li>
</ul>
</li>
</ul>
</blockquote>
<p>  <strong>隐式的事务：</strong> 事务没有明显的开启和结束标记。比如单独的 insert、update、delete语句（DML）。使用 <code>show variables like &#39;autocommit&#39;</code> 可以看到默认的值为ON，表示开启了自动事务提交。<br>  <strong>显式的事务：</strong> 事务具有明显的开启和结束标记。前提是必须先设置自动提交功能为禁用。<code>set autocommit = 0;</code> 该方法只对当前Session有效。多条sql语句要想以事务的方式执行，就可以使用隐式的事务，先禁用掉 autocommit。</p>
<h4 id="B、多语句以事务的方式执行"><a href="#B、多语句以事务的方式执行" class="headerlink" title="B、多语句以事务的方式执行"></a>B、多语句以事务的方式执行</h4><blockquote>
<p>多语句以事务的方式执行：</p>
<ul>
<li><font color="#e96900">步骤一：开始显式的事务<br>set autocommit &#x3D; 0;<br>start transaction;<br>步骤二：编写事务中的多条sql语句（select、insert、update、delete）;<br>语句1;<br>语句2;<br>……<br>步骤三：结束事务<br>commit;提交事务<br>rollback;回滚事务</font></li>
<li>只是针对DQL语言和DML语言来说有事务，对于DDL语言（数据库和表结构的定义）来说，一般不谈论事务。</li>
</ul>
</blockquote>
<blockquote>
<p>演示事务的使用步骤</p>
<ul>
<li>先建个表：<ul>
<li><font color="#e96900">drop table if exists account;<br>  create table account(<br>    id INT PRIMARY KEY AUTO_INCREMENT,<br>    username VARCHAR(20),<br>    balance DOUBLE<br>  );</font></li>
</ul>
</li>
<li>插入数据进去：<ul>
<li><font color="#e96900">insert into account(username, balance)<br>  values(&#39;A&#39;, 1000),(&#39;B&#39;, 1000);</font></li>
</ul>
</li>
<li>转账事务正常提交演示：<ul>
<li><font color="#e96900">SET autocommit&#x3D;0;<br>  START TRANSACTION;<br>  update account set balance&#x3D;balance-500 where username&#x3D;&#39;A&#39;;<br>  update account set balance&#x3D;balance+500 where username&#x3D;&amp;#39B;&#39;;<br>  commit;</font></li>
</ul>
</li>
<li>转账事务回滚演示：<ul>
<li><font color="#e96900">SET autocommit&#x3D;0;<br>  START TRANSACTION;<br>  update account set balance&#x3D;balance-500 where username&#x3D;&#39;A&#39;;<br>  update account set balance&#x3D;balance+500 where username&#x3D;&amp;#39B;&#39;;<br>  rollback;  </font></li>
</ul>
</li>
</ul>
</blockquote>
<h4 id="C、并发事务控制"><a href="#C、并发事务控制" class="headerlink" title="C、并发事务控制"></a>C、并发事务控制</h4><blockquote>
<ul>
<li><strong>对于同时运行的多个事务，当这些事务访问数据库中的相同数据时，如果没有采取必要的隔离机制，就会导致各种并发问题。</strong><ul>
<li><strong>脏读：</strong> 对于两个事务T1，T2。事务T1读取了被T2更新但还<strong>没有被提交</strong>的字段，之后若T2回滚，那么T1读取的内容就是临时且无效的脏数据。</li>
<li><strong>不可重复读：</strong> 对于两个事务T1，T2。事务T1读取了一个字段，然后T2<strong>更新</strong>了该字段，之后T1再次读取同一个字段，值就不同了。</li>
<li><strong>幻读：</strong> 对于两个事务T1，T2。事务T1从表中读取了一个字段，然后T2在该表中<strong>插入</strong>了一些新的行，之后T1再次读取同一个表，就会多出几行。</li>
</ul>
</li>
<li><strong>数据库事务的隔离性：数据库系统必须具有隔离并发运行各个事务的能力，使它们不会相互影响，避免各种并发问题。</strong></li>
<li><font color="#e96900">一个事务与其他事务隔离的程度称为隔离级别。</font>数据库规定了很多事务的隔离级别，不同的隔离级别对应不同的干扰程度，<font color="#e96900">隔离级别越高，数据一致性就越好，但并发性越弱</font>。</li>
<li><strong>数据库提供的4中事务隔离级别</strong><ul>
<li><font color="#e96900"><strong>读未提交（READ UNCOMMITTED）：</strong></font>允许事务读取其他事务提交的变更。脏读、不可重复读和幻读的问题都会出现。</li>
<li><font color="#e96900"><strong>读已提交（READ COMMITTED）：</strong></font>只允许事务读取已经被其他事务提交的变更。可以避免脏读，但是不可重复读和幻读的问题仍然可能出现。</li>
<li><font color="#e96900"><strong>可重复读（REPEATABLE READ）：</strong></font>确保事物可以多次从一个字段中读取相同的值，在这个事务持续期间，禁止其他事务对这个字段进行更新。可以避免脏读和不可重复读，但是幻读的问题仍然存在。</li>
<li><font color="#e96900"><strong>串行化（SERIALIZABLE）：</strong></font>确保事务可以从一个表中读取相同的行，在这个事务持续期间，禁止其他事务对该表执行插入，更新和删除操作。所有并发问题都可以避免，但是性能十分低下。</li>
</ul>
</li>
<li><strong>Oracle 支持的2种事务隔离级别：READ COMMITTED，SERIALIZABLE。Oracle 默认的事务隔离级别为：READ COMMITTED</strong></li>
<li><strong>MySql 支持以上4种事务的隔离级别。MySql默认的事务隔离级别为：REPEATABLE READ</strong></li>
<li>每启动一个mysql程序，就会获得一个单独的数据库连接，每个数据库连接都有一个全局变量 <font color="#e96900">@@tx_isolation</font> ，表示当前的事务隔离级别</li>
<li>查看当前的隔离级别：<code>SELECT @@tx_isolation;</code></li>
<li>设置当前mysql连接的隔离级别：<code>set session transaction isolation level read committed;</code></li>
<li>设置数据库系统的全局的隔离级别：<code>set global transaction isolation level read committed;</code></li>
</ul>
</blockquote>
<h4 id="D、回滚点（savepoint）"><a href="#D、回滚点（savepoint）" class="headerlink" title="D、回滚点（savepoint）"></a>D、回滚点（savepoint）</h4><blockquote>
<ul>
<li><font color="#e96900">savepoint 节点名;</font> #设置保存点</li>
<li>演示 savepoint 的使用（只能搭配 rollback 使用）<ul>
<li><font color="#e96900">set autocommit&#x3D;0;<br>  start transaction;<br>  delete from account where id &#x3D; 1;<br>  savepoint a;<br>  delete from account where id &#x3D; 2;<br>  rollback to a;</font></li>
</ul>
</li>
</ul>
</blockquote>
<h4 id="E、事务中的delete和truncate"><a href="#E、事务中的delete和truncate" class="headerlink" title="E、事务中的delete和truncate"></a>E、事务中的delete和truncate</h4><blockquote>
<p>事务中使用delete时，能被正常回滚，数据不会被删除掉</p>
<ul>
<li><font color="#e96900">set autocommit&#x3D;0;<br>start transaction;<br>delete from account;<br>rollback;</font></li>
</ul>
<p>事务中使用truncate时，不能回滚被删除的数据，数据会被真的删除掉</p>
<ul>
<li><font color="#e96900">set autocommit&#x3D;0;<br>start transaction;<br>truncate table account;<br>rollback;</font></li>
</ul>
<p><strong>总结：</strong></p>
<ul>
<li>事务中的delete能被正常回滚，记录只是被标记上删除，但实际上还并未被删除；而事务中的truncate没办法正常回滚，数据是真的被删除了。</li>
<li>再啰嗦一句：truncate删除全表数据后，再插入数据时，表中的自增长列会重新从1开始自增；而delete删除数据后，再插入数据时，表中的自增长列还是从原来的断点处继续自增。</li>
<li>truncate只支持删除全表记录，不支持筛选条件。delete支持按照筛选条件删除。</li>
</ul>
</blockquote>
<hr>
<h3 id="七、DCL-数据库控制语言"><a href="#七、DCL-数据库控制语言" class="headerlink" title="七、DCL 数据库控制语言"></a>七、DCL 数据库控制语言</h3><p>  <strong>Data Control Language</strong></p>
<h4 id="A、用户角色权限控制"><a href="#A、用户角色权限控制" class="headerlink" title="A、用户角色权限控制"></a>A、用户角色权限控制</h4><p><strong>待续。。。。。。</strong></p>
<hr>
<h3 id="八、视图"><a href="#八、视图" class="headerlink" title="八、视图"></a>八、视图</h3><p>  视图其实就是一个虚拟的表，可以和普通的表一样使用。mysql5.1版本出现的新特性，是通过现有的的表动态生成的数据，并且是在使用视图时才动态生成，<font color="#e96900"><strong>只保存了sql逻辑，不保存查询结果。</strong></font>当多个地方用到同样的查询结果或该查询结果使用的sql语句较为复杂时可以使用视图功能。</p>
<blockquote>
<p>案例：查询姓张的学生名和专业名</p>
<ul>
<li><font color="#e96900">select stuname, majorname<br>from stuinfo s<br>inner join major m on s.majorid&#x3D;m.id<br>where stuname like &#39;张%&#39;;</font></li>
<li><font color="#e96900">create view v1<br>as<br>select stuname, majorname<br>from stuinfo s inner join major m on s.majorid&#x3D;m.id;</font></li>
<li><font color="#e96900">select * from v1 where stuname like &#39;张%&#39;;</font></li>
</ul>
</blockquote>
<h4 id="A、视图的创建"><a href="#A、视图的创建" class="headerlink" title="A、视图的创建"></a>A、视图的创建</h4><blockquote>
<p>语法：</p>
<ul>
<li><font color="#e96900" size="4">create view 视图名<br>as<br>查询语句;</font></li>
</ul>
<p>案例1：查询姓名包含a字符的员工名，部门名和工种信息</p>
<ol>
<li><font color="#e96900">create view myview1<br>as<br>select last_name, department_name, job_title<br>from employees e<br>join departments d on e.department_id&#x3D;d.department_id<br>join jobs j on e.job_id &#x3D; j.job_id;</font></li>
<li><font color="#e96900">select * from myview1 where last_name like &quot;%a%&quot;;</font></li>
</ol>
<p>案例2：查询各部门的平均工资级别</p>
<ol>
<li>创建视图查看各部门平均工资<br><font color="#e96900">create view myv2 as<br>select AVG(salary) avg_sal, department_id<br>from employees<br>group by department_id;</font></li>
<li>使用视图<br><font color="#e96900">select m.avg_sal, g.grade_level<br>from myv2 m<br>join job_grades g on m.avg_sal between g.lowest_sal and g.highest_sal;</font></li>
</ol>
<p>案例3：查询平均工资最低的部门信息</p>
<ul>
<li><font color="#e96900">直接使用以上创建好的视图myv2<br>select d.*<br>from departments d<br>where d.department_id &#x3D; (<br>  select department_id from myv2 order by avg_sal limit 1<br>);</font></li>
</ul>
</blockquote>
<ul>
<li>视图可以重用sql语句</li>
<li>简化了复杂的sql操作，不必知道它的查询细节</li>
<li>保护数据，提高了安全性（因为不知道原表的情况）</li>
</ul>
<h4 id="B、视图的修改"><a href="#B、视图的修改" class="headerlink" title="B、视图的修改"></a>B、视图的修改</h4><blockquote>
<p>方式一：</p>
<ul>
<li><font color="#e96900" size="4">create or replace view 视图名<br>as<br>查询语句;</font></li>
<li><strong>若视图存在，则替换；若视图不存在，则创建</strong></li>
<li><strong><code>create or replace view myv2 as select * from employees;</code></strong></li>
</ul>
<p>方式二：</p>
<ul>
<li><font color="#e96900" size="4">alter view 视图名<br>as<br>查询语句;</font></li>
<li><strong><code>alter view myv2 as select * from departments;</code></strong></li>
</ul>
</blockquote>
<h4 id="C、视图的删除"><a href="#C、视图的删除" class="headerlink" title="C、视图的删除"></a>C、视图的删除</h4><blockquote>
<p>语法：</p>
<ul>
<li><font color="#e96900" size="4">drop view 视图名, 视图名, …;</font></li>
<li><font color="#e96900" size="4">drop view if exists 视图名, 视图名, …;</font></li>
<li><code>drop view if exists myview1, myv2;</code></li>
</ul>
</blockquote>
<h4 id="D、查看视图的结构"><a href="#D、查看视图的结构" class="headerlink" title="D、查看视图的结构"></a>D、查看视图的结构</h4><p>  类似于表的查看。</p>
<blockquote>
<p>先创建一个视图</p>
<ul>
<li><font color="#e96900">create or replace view myview as<br>select * from employees;</font></li>
</ul>
<p>查看视图的结构</p>
<ul>
<li><font color="#e96900">desc myview;</font></li>
<li><font color="#e96900">show create view myview;</font> 能看到创建视图时的sql语句</li>
</ul>
</blockquote>
<h4 id="E、视图的更新"><a href="#E、视图的更新" class="headerlink" title="E、视图的更新"></a>E、视图的更新</h4><p>  这里视图的更新并不是指的视图的逻辑修改，而是指视图的逻辑不变，而视图中数据的更新。</p>
<blockquote>
<p>1、先来创建两个视图</p>
<ul>
<li><font color="#e96900">create or replace view myview1 as<br>select last_name, email, salary*12*(1+IFNULL(commission_pct, 0)) annual_salary<br>from employees;</font></li>
<li><font color="#e96900">create or replace view myview2 as<br>select last_name, email<br>from employees;</font></li>
</ul>
<p>2、查看视图中的数据</p>
<ul>
<li><font color="#e96900">select * from myview1;</font></li>
<li><font color="#e96900">select * from myview2;</font></li>
</ul>
<p>3、<strong>插入</strong>数据到视图中</p>
<ul>
<li><font color="#e96900">insert into myview1 values(&#39;A&#39;, &#39;<a href="mailto:&#97;&#97;&#97;&#64;&#113;&#x71;&#x2e;&#99;&#x6f;&#x6d;">&#97;&#97;&#97;&#64;&#113;&#x71;&#x2e;&#99;&#x6f;&#x6d;</a>&#39;, 1000000), (&#39;B&#39;, &#39;<a href="mailto:&#x62;&#98;&#98;&#x40;&#113;&#x71;&#x2e;&#99;&#111;&#109;">&#x62;&#98;&#98;&#x40;&#113;&#x71;&#x2e;&#99;&#111;&#109;</a>&#39;, 1100000);</font><br><font color="#0000ee">报错：Column ‘annual_salary’ is not updatable. 并不是所有的字段都能更新。</font></li>
<li><font color="#e96900">insert into myview2 values(&#39;A&#39;, &#39;<a href="mailto:&#97;&#x61;&#x61;&#x40;&#113;&#x71;&#x2e;&#99;&#111;&#109;">&#97;&#x61;&#x61;&#x40;&#113;&#x71;&#x2e;&#99;&#111;&#109;</a>&#39;), (&#39;B&#39;, &#39;<a href="mailto:&#98;&#x62;&#x62;&#64;&#x71;&#113;&#46;&#99;&#x6f;&#x6d;">&#98;&#x62;&#x62;&#64;&#x71;&#113;&#46;&#99;&#x6f;&#x6d;</a>&#39;);</font><br><font color="#0000ee">成功插入，并且会插入到原始表中。这个时候由于原始表有了新数据，视图myview1中的数据也会变多，因为myview1是由原始表动态生成的。</font></li>
</ul>
<p>4、<strong>修改</strong>视图中的数据</p>
<ul>
<li><font color="#e96900">update myview1 set last_name&#x3D;&quot;AAAAA&quot; where last_name&#x3D;&quot;A&quot;;</font><br><font color="0000ee">成功修改，原始表中的数据也会被修改，本质上就是修改的原始表中的数据，因为视图就是一个sql逻辑而已，并不保存数据，数据都是在原始表上的。</font></li>
<li><font color="#e96900">update myview2 set last_name&#x3D;&quot;A&quot; where last_name&#x3D;&quot;AAAAA&quot;;</font><br><font color="0000ee">同上，成功修改。</font></li>
<li><font color="#e96900">update myview1 set annual_salary&#x3D;3000000 where last_name&#x3D;&quot;A&quot;;</font><br><font color="0000ee">这个会报错：Column ‘annual_salary’ is not updatable。</font></li>
</ul>
<p>5、<strong>删除</strong>视图中的数据</p>
<ul>
<li><font color="#e96900">delete from myview1 where last_name in (&quot;A&quot;, &quot;B&quot;);</font><br><font color="0000ee">同样，删除的是原始表中的数据，会同时影响myview1和myview2。</font></li>
</ul>
</blockquote>
<p><strong>注意：视图的可更新性与创建视图时定义的查询有关，以下类型的视图是不能更新的</strong></p>
<ul>
<li>包含以下关键字的sql语句：分组函数、distinct、group by、having、union、或者 union all</li>
<li>常量视图 <code>create view v as select &#39;常量1&#39;;</code></li>
<li>select 中包含子查询</li>
<li>join 关联查询</li>
<li>from 一个不能更新的视图</li>
<li>where 子句的子查询引用了from子句中的表</li>
</ul>
<h4 id="F、视图和表的对比"><a href="#F、视图和表的对比" class="headerlink" title="F、视图和表的对比"></a>F、视图和表的对比</h4><ul>
<li>创建视图和表所使用的关键字不一样，<code>&quot;create view&quot;</code> <code>&quot;create table&quot;</code></li>
<li>视图只是保存了一组sql逻辑，不保存数据；数据都在原始的表中</li>
<li>视图也是能增删改的，但是有些情况下不能增删改，一般也不使用其增删改的功能</li>
</ul>
<hr>
<h3 id="九、变量"><a href="#九、变量" class="headerlink" title="九、变量"></a>九、变量</h3><ul>
<li>系统变量<ul>
<li>全局变量（针对于mysql服务器有效）</li>
<li>会话变量（只针对当前会话，或一次客户端连接有效）</li>
</ul>
</li>
<li>自定义变量<ul>
<li>用户变量（类似于java的全局变量）</li>
<li>局部变量（类似于java的局部变量）</li>
</ul>
</li>
</ul>
<h4 id="A、系统变量（全局、会话）"><a href="#A、系统变量（全局、会话）" class="headerlink" title="A、系统变量（全局、会话）"></a>A、系统变量（全局、会话）</h4><p>  由MySql系统为我们提供的变量，不是用户定义的，属于服务器层面的。分为<strong>全局变量</strong>和<strong>会话变量</strong>。因为这些变量由系统提供，所以并不需要我们自己定义，我们只需要学会如何去<strong>查看</strong>和<strong>赋值</strong>就行。如果是操作全局变量，则需要加global关键字；如果是操作会话变量，则可以加上session关键字；如果不加这两关键字，则默认操作会话变量。<br>  对于全局变量来说，mysql服务器每次启动会为所有的全局变量赋初始值，可以修改全局变量的值，针对于所有的会话（连接）有效，但不能跨重启，也就是说每次mysql重启后，全局变量的值会被重新初始化。如果要想每次重启后都是修改后的值，那得去改配置文件了。<br>  对于会话变量来说，会话变量仅仅针对于当前会话（连接）有效。实测后发现，会话变量比全局变量多。</p>
<blockquote>
<p><strong>1、查看所有的系统变量：</strong></p>
<ul>
<li><strong><code>show global variables;</code></strong> global表示全局变量</li>
<li><strong><code>show session variables;</code></strong> session表示会话变量</li>
<li><strong><code>show variables;</code></strong> 默认表示查看会话变量</li>
</ul>
<p><strong>2、查看满足条件的系统变量（模糊查询）：</strong></p>
<ul>
<li><strong><code>show global variables like &#39;模糊查询条件&#39;;</code></strong></li>
<li><strong><code>show session variables like &#39;模糊查询条件&#39;;</code></strong></li>
<li><strong><code>show variables like &#39;模糊查询条件&#39;;</code></strong></li>
<li>比如：<code>show variables like &#39;%character_set%&#39;;</code></li>
</ul>
<p><strong>3、查看指定的某个系统变量的值：</strong></p>
<ul>
<li><strong><code>select @@global.系统变量名;</code></strong> global表示全局变量</li>
<li><strong><code>select @@session.系统变量名;</code></strong> session表示会话变量</li>
<li><strong><code>select @@系统变量名;</code></strong> 默认表示会话变量</li>
<li>比如：<code>select @@character_set_client;</code></li>
</ul>
<p><strong>4、为某个系统变量赋值：</strong></p>
<ul>
<li>方式一：<ul>
<li><code>set global 系统变量名 = 值;</code></li>
<li><code>set session 系统变量名 = 值;</code></li>
<li><code>set 系统变量名 = 值;</code></li>
<li>比如：<code>set autocommit = 0;</code></li>
</ul>
</li>
<li>方式二：<ul>
<li><code>set @@global.系统变量名 = 值;</code></li>
<li><code>set @@session.系统变量名 = 值;</code></li>
<li><code>set @@系统变量 = 值;</code></li>
<li>比如：<code>set @@autocommit = 0;</code></li>
</ul>
</li>
</ul>
</blockquote>
<h4 id="B、自定义变量（用户、局部）"><a href="#B、自定义变量（用户、局部）" class="headerlink" title="B、自定义变量（用户、局部）"></a>B、自定义变量（用户、局部）</h4><p>  用户自己定义的变量，不是由系统提供的。必须在用户声明、赋值后才能使用（查看，比较，运算等）。</p>
<blockquote>
<p><strong>1、用户变量</strong><br>  用户变量的作用域为：针对当前会话（连接）有效，等同于会话变量的作用域。可以应用在任何地方，begin end 里或则begin end外都行。</p>
<ul>
<li>① 声明并初始化（用户变量在声明时必须初始化）<ul>
<li>方式一： <font color="#e96900">set @用户变量名 &#x3D; 值;</font></li>
<li>方式二： <font color="#e96900">set @用户变量名 :&#x3D; 值;</font></li>
<li>方式三： <font color="#e96900">select @用户变量 :&#x3D; 值;</font></li>
<li>赋值的操作符为 “&#x3D;” 或 “:&#x3D;”。在使用set来声明变量时，”&#x3D;” 或 “:&#x3D;” 都可以当做赋值操作符来使用；但是在使用select来声明变量时，只能将 “:&#x3D;” 当做赋值操作符来使用。</li>
</ul>
</li>
<li>② 赋值（更新用户变量的值）<ul>
<li>方式一：通过 <strong>SET</strong> 或 <strong>SELECT</strong>。同上（既能当声明用又能当赋值用）。<ul>
<li><code>set @name = &#39;john&#39;;</code></li>
<li><code>set @name = 100;</code></li>
<li><code>set @count := 0;</code></li>
</ul>
</li>
<li>方式二：通过 <strong>SELECT INTO</strong>。<ul>
<li><font color="#e96900">select 字段 into @用户变量名 from 某表;</font></li>
<li><code>select count(*) into @count from employees;</code></li>
</ul>
</li>
</ul>
</li>
<li>③ 简单使用（查看用户变量的值）<ul>
<li><font color="#e96900">select @系统变量名;</font></li>
<li><code>select @count;</code></li>
</ul>
</li>
</ul>
</blockquote>
<blockquote>
<p><strong>2、局部变量</strong><br>  局部变量的作用域为：仅仅在定义它的begin end中有效。也就是说局部变量只能应用在begin end中，而且<strong>只能放在begin end中的第一句话中声明</strong>，生命周期很短。</p>
<ul>
<li>① 声明<ul>
<li><font color="#e96900">DECLARE 变量名 类型;</font></li>
<li><font color="#e96900">DECLARE 变量名 类型 DEFAULT 值;</font></li>
</ul>
</li>
<li>② 赋值<ul>
<li>方式一：通过 <strong>SET</strong> 或 <strong>SELECT</strong>。<ul>
<li><font color="#e96900">set 局部变量名 &#x3D; 值;</font></li>
<li><font color="#e96900">set 局部变量名 :&#x3D; 值;</font></li>
<li><font color="#e96900">select @局部变量名 :&#x3D; 值;</font></li>
</ul>
</li>
<li>方式二：通过 <strong>SELECT INTO</strong>。<ul>
<li><font color="#e96900">select 字段 into 局部变量名 from 某表;</font></li>
<li><code>select count(*) into aaa from employees;</code></li>
</ul>
</li>
</ul>
</li>
<li>③ 简单使用<ul>
<li><font color="#e96900">SELECT 局部变量名;</font></li>
</ul>
</li>
</ul>
</blockquote>
<blockquote>
<p><strong>3、用户变量和局部变量的对比</strong></p>
<ul>
<li>用户变量的作用域为当前会话；而局部变量的作用域为begin end中</li>
<li>用户变量可以使用在会话中的任何位置；而局部变量只能放在begin end的第一句话中声明</li>
<li>用户变量必须加 @ 符号；而局部变量一般不用加 @ 符号，当使用select赋值时需要加 @ 符号</li>
<li>用户变量不需要限定变量的类型；而局部变量需要在声明时限定变量的类型</li>
</ul>
</blockquote>
<blockquote>
<p><strong>4、使用案例</strong></p>
<ul>
<li>案例1：声明两个变量并赋值，求和，并打印<ul>
<li>方式一：使用用户变量<br>  <font color="#e96900">set @m &#x3D; 1;<br>  set @n &#x3D; 2;<br>  set @sum &#x3D; @m + @n;<br>  select @sum;</font></li>
<li>方式二：使用局部变量<br>  <font color="#e96900">declare m int default 1;<br>  declare n int default 2;<br>  declare sum;<br>  set sum &#x3D; m + n;<br>  select sum;</font></li>
</ul>
</li>
</ul>
</blockquote>
<hr>
<h3 id="十、存储过程和函数"><a href="#十、存储过程和函数" class="headerlink" title="十、存储过程和函数"></a>十、存储过程和函数</h3><p>  存储过程和函数，类似于java中的方法。</p>
<h4 id="A、存储过程"><a href="#A、存储过程" class="headerlink" title="A、存储过程"></a>A、存储过程</h4><p>  存储过程就是一组预先编译好的SQL语句的集合，批处理语句。提高了代码的重用性，简化操作，减少了编译次数并且减少了和数据库服务器的连接次数，提高效率。</p>
<blockquote>
<p><strong><font color="#0000ee">1、创建存储过程</font></strong></p>
<ul>
<li><font color="#e96900">create procedure 存储过程名(参数列表)<br>BEGIN<br>  存储过程体(一组合法有效的sql语句)<br>END</font></li>
<li>注意事项<ul>
<li>参数列表包含三部分信息：参数模式、参数名、参数类型。比如 <strong><code>IN stuname VARCHAR(20)</code></strong> 。</li>
<li>其中参数模式有三种，分别是：<font color="#e96900">IN，OUT，INOUT</font><ul>
<li><strong>INT</strong> 参数模式表示该参数可以作为输入，也就是该参数需要调用方传入值。</li>
<li><strong>OUT</strong> 参数模式表示该参数可以作为输出，也就是该参数可以作为返回值。</li>
<li><strong>INOUT</strong> 参数模式表示该参数既可以作为输入，又可以作为输出，也就是该参数既需要传入值，又可以返回值。</li>
</ul>
</li>
<li>如果省略了参数模式，增默认的参数模式为 IN</li>
<li>如果存储过程仅仅只有一句话，那么 BEGIN END 可以省略</li>
<li>存储过程中的每条SQL语句的结尾要求必须加 <font color="#e96900">分号</font></li>
<li>存储过程的结尾可以使用 <font color="#e96900">delimiter</font> 关键字来重新设置<ul>
<li>语法： <strong><code>DELIMITER 结束标记</code></strong></li>
<li>比如：<code>delimiter $</code></li>
</ul>
</li>
</ul>
</li>
</ul>
<p><strong><font color="#0000ee">2、调用存储过程</font></strong></p>
<ul>
<li><font color="#e96900">CALL 存储过程名(实参列表);</font></li>
</ul>
<p><strong><font color="#0000ee">3、空参的存储过程</font></strong></p>
<ul>
<li>案例：插入到admin表中五条记录<ul>
<li><font color="#e96900">delimiter $<br>  create procedure myp1()<br>  begin<br>    insert into admin(username, `password`)<br>    values(&#39;A&#39;, &#39;0000&#39;), (&#39;B&#39;, &#39;0000&#39;), (&#39;C&#39;, &#39;0000&#39;), (&#39;D&#39;, &#39;0000&#39;), (&#39;E&#39;, &#39;0000&#39;);<br>  end $</font></li>
<li>调用：<font color="#e96900">call myp1();</font></li>
</ul>
</li>
</ul>
<p><strong><font color="#0000ee">4、带 IN 参数模式的存储过程</font></strong></p>
<ul>
<li>案例1：创建存储过程，根据女神名，查询对应的男神信息<ul>
<li><font color="#e96900">delimiter $<br>  create procedure myp2(in beautyName varchar(20))<br>  begin<br>    select bo.*<br>    from boys bo<br>    right join beauty b on bo.id&#x3D;b.boyfriend_id<br>    where b.name&#x3D;beautyName;<br>  end $</font></li>
<li>调用方式一：<font color="#e96900">call myp2(&#39;赵敏&#39;);</font></li>
<li>调用方式二：（新建一个变量作为参数传入）<ul>
<li><font color="#e96900">set @beautyName&#x3D;&#39;赵敏&#39;;<br>  call myp2(@beautyName);</font></li>
</ul>
</li>
</ul>
</li>
<li>案例2：创建存储过程，实现判断用户是否登录成功<ul>
<li><font color="#e96900">delimiter $<br>  create procedure myp3(in username varchar(20), in password varchar(20))<br>  begin<br>    declare result int default 0; #① 声明并初始化<br>    select count(*) into result #② 赋值<br>    from admin<br>    where admin.username&#x3D;username<br>    and admin.`password`&#x3D;password;<br>    select if(result&gt;0, &#39;成功&#39;, &#39;失败&#39;); #③ 使用<br>  end $</font></li>
<li>调用：<font color="#e96900">call myp3(&#39;A&#39;, &#39;0000&#39;);</font> 返回”成功”</li>
<li>调用：<font color="#e96900">call myp3(&#39;A&#39;, &#39;1111&#39;);</font> 返回”失败”</li>
</ul>
</li>
</ul>
<p><strong><font color="#0000ee">5、带 OUT 参数模式的存储过程</font></strong></p>
<ul>
<li>案例1：根据女神名，返回对应的男神名<ul>
<li><font color="#e96900">delimiter $<br>  create procedure myp4(in beautyName varchar(20), out boyName varchar(20))<br>  begin<br>    select bo.boyName into boyName<br>    from boys bo<br>    inner join beauty b on bo.id&#x3D;b.boyfriend_id<br>    where b.name&#x3D;beautyName;<br>  end $</font></li>
<li>调用：<ul>
<li><font color="#e96900">call myp4(&#39;赵敏&#39;, @bName);</font></li>
<li><font color="#e96900">select @bName;</font></li>
</ul>
</li>
</ul>
</li>
<li>案例2：根据女神名，返回对应的男神名和男神魅力值<ul>
<li><font color="#e96900">delimiter $<br>  create procedure myp5(in beautyName varchar(20), out boyName varchar(20), out userCp int)<br>  begin<br>    select bo.boyName,bo.userCp into boyName, userCp<br>    from boys bo<br>    inner join beauty b on bo.id&#x3D;b.boyfriend_id<br>    where b.name&#x3D;beautyName;<br>  end $</font></li>
<li>调用<ul>
<li><font color="#e96900">call myp5(&#39;赵敏&#39;, @bName, @userPc);</font></li>
<li><font color="#e96900">select @bName, @userPc;</font></li>
</ul>
</li>
</ul>
</li>
</ul>
<p><strong><font color="#0000ee">6、带 INOUT 参数模式的存储过程</font></strong></p>
<ul>
<li>案例：传入a和b两个值，最终a和b都翻倍并返回<ul>
<li><font color="#e96900">delimiter $<br>  create procedure myp6(inout a int, inout b int)<br>  begin<br>    set a &#x3D; 2 * a;<br>    set b &#x3D; 2 * b;<br>  end $</font></li>
<li>调用：<ul>
<li><font color="#e96900">set | [select] @a:&#x3D;2, @b:&#x3D;3;</font> #首先需要定义出变量</li>
<li><font color="#e96900">call myp6(@a, @b);</font></li>
<li><font color="#e96900">select @a, @b;</font></li>
</ul>
</li>
</ul>
</li>
</ul>
<p><strong><font color="#0000ee">7、存储过程的删除</font></strong></p>
<ul>
<li><font color="#e96900">drop procedure 存储过程名;</font></li>
<li><font color="#e96900">drop procedure if exists 存储过程名;</font></li>
</ul>
<p><strong><font color="#0000ee">8、存储过程的查看</font></strong></p>
<ul>
<li><font color="#e96900">desc 存储过程名;</font> <strong>错误语法，desc只能用来查看表或视图的结构</strong></li>
<li><font color="#e96900">show create procedure 存储过程名;</font> 正确语法<ul>
<li><code>show create procedure myp6;</code></li>
</ul>
</li>
<li>查看所有的存储过程：<font color="#e96900"><strong>show procedure status;</strong></font></li>
<li>存储过程不能修改，要想修改，只能删掉重建。</li>
</ul>
</blockquote>
<h4 id="B、函数"><a href="#B、函数" class="headerlink" title="B、函数"></a>B、函数</h4><p>  函数与存储过程非常的相似，存储过程可以有0个或多个返回值，函数有且只能有1个返回值。存储过程适合做批量插入，批量更新的操作；函数适合用来处理数据后返回一个结果。</p>
<blockquote>
<p><strong><font color="#0000ee">1、函数的创建</font></strong></p>
<ul>
<li><font color="#e96900" size="4">create function 函数名(参数列表) returns 返回类型<br>begin<br>  函数体<br>end</font></li>
<li>注意事项<ul>
<li>参数列表包含两部分：参数名和参数类型。</li>
<li>函数体中肯定会有 return 语句，如果没有就会报错。如果return语句没有放在函数体的最后也不会报错，但是不建议这样用。</li>
<li>当函数体中只用一句话时，则可以省略begin end</li>
<li>存储过程中的每条SQL语句的结尾要求必须加 <font color="#e96900">分号</font></li>
<li>存储过程的结尾可以使用 <font color="#e96900">delimiter</font> 关键字来重新设置<ul>
<li>语法： <strong><code>DELIMITER 结束标记</code></strong></li>
<li>比如：<code>delimiter $</code></li>
</ul>
</li>
</ul>
</li>
</ul>
<p><strong><font color="#0000ee">2、函数的调用</font></strong></p>
<ul>
<li><font color="#e96900" size="4">select 函数名(实参列表);</font></li>
<li>执行函数中的所有语句，并且查询出返回值，函数一定要有返回值<blockquote>
<p><strong>案例1（无参有返回）：返回公司的员工个数</strong></p>
<ul>
<li><font color="#e96900">delimiter $<br>create function myf1() returns int<br>begin<br>  declare result int default 0; #定义局部变量<br>  select count(*) into result from employees;<br>  return result;<br>end $</font></li>
<li>可能会报错 <code>This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)</code>。需要设置一下全局变量的值：<code>set @@global.log_bin_trust_function_creators=1;</code></li>
<li>调用：<font color="#e96900">select myf1();</font></li>
</ul>
<p><strong>案例2（带参有返回值）：根据员工名，返回他的工资</strong></p>
<ul>
<li><font color="#e96900">delimiter $<br>create function myf2(empName varchar(20)) returns double<br>begin<br>  set @sal&#x3D;0.0; #也可以定义用户变量<br>  select salary into @sal<br>  from employees;<br>  where last_name&#x3D;empName;<br>  return @sal;<br>end $</font></li>
<li>调用：<font color="#e96900">select myf2(&#39;Kochhar&#39;);</font></li>
<li>注意：当查询结果多于一条时会报错 <code>Result consisted of more than one row</code></li>
</ul>
<p><strong>案例3（带参有返回值）：根据部门名，返回该部门的平均工资</strong></p>
<ul>
<li><font color="#e96900">delimiter $<br>create function myf3(deptName varchar(20)) returns double<br>begin<br>  declare sal double; #定义局部变量<br>  select avg(salary) into sal<br>  from employees e<br>  join departments d on e.department_id&#x3D;d.department_id<br>  where d.department_name&#x3D;deptName;<br>  return sal;<br>end $</font></li>
<li>调用：<font color="#e96900">select myf3(&#39;IT&#39;);</font></li>
</ul>
</blockquote>
</li>
</ul>
<p><strong><font color="#0000ee">3、函数的删除</font></strong></p>
<ul>
<li><font color="#e96900">drop function 函数名;</font></li>
<li><font color="#e96900">drop function if exists 函数名;</font></li>
</ul>
<p><strong><font color="#0000ee">4、函数的查看</font></strong></p>
<ul>
<li><font color="#e96900">desc 函数名;</font> <strong>错误语法，desc只能用来查看表或视图的结构</strong></li>
<li><font color="#e96900">show create function 函数名;</font> 正确语法<ul>
<li><code>show create function myf1;</code></li>
</ul>
</li>
<li>查看所有的函数：<font color="#e96900"><strong>show function status;</strong></font></li>
<li>同样函数也不能修改，要想修改，只能删掉重建。</li>
</ul>
</blockquote>
<hr>
<h3 id="十一、流程控制结构"><a href="#十一、流程控制结构" class="headerlink" title="十一、流程控制结构"></a>十一、流程控制结构</h3><p>  顺序结构是指程序从上往下依次执行。分支结构是指程序从两条或多条执行路径中选择一条去执行。循环结构是指程序在满足一定条件的基础上，重复执行一段代码。</p>
<h4 id="A、分支结构"><a href="#A、分支结构" class="headerlink" title="A、分支结构"></a>A、分支结构</h4><blockquote>
<p><strong><font color="#0000ee">1、if函数（实现简单的双分支）</font></strong></p>
<ul>
<li><p><code>IF(表达式1, 表达式2, 表达式3);</code> 如果表达式1成立，则if函数返回表达式2的值，否则返回表达式3的值。这个函数可以放在任何地方使用，比如 select 语句中，begin end 中也可以使用。<br><strong><font color="0000ee">2、case结构（可实现多分支）</font></strong></p>
</li>
<li><p><strong>情况一：类似于java中的switch语句，一般用于实现等值判断</strong></p>
<table>
<thead>
<tr>
<th>java中</th>
<th>mysql中</th>
</tr>
</thead>
<tbody><tr>
<td><font color="#e96900">switch (变量或表达式) {<br>  case 常量1: 语句1; break;<br>  …<br>  defualt: 语句n; break;<br>}</font></td>
<td><font color="#e96900">case 要判断的字段、变量或表达式 <br>when 常量1 then 返回的值1或 语句1;<br>when 常量2 then 返回的值2或 语句2;<br>…<br>else 返回的值n或 语句n;<br>end case;</font></td>
</tr>
</tbody></table>
</li>
<li><p><strong>情况二：类似于java中的多重if语句，一般用于实现区间判断</strong></p>
<table>
<thead>
<tr>
<th>java中</th>
<th>mysql中</th>
</tr>
</thead>
<tbody><tr>
<td><font color="#e96900">if (条件1) { 语句1; }<br>else if (条件2) { 语句2; }<br>…<br>else { 语句n; }</font></td>
<td><font color="#e96900">case<br>when 条件1 then 返回的值1或 语句1;<br>when 条件2 then 返回的值2或 语句2;<br>…<br>else 返回的值n或 语句n;<br>end case;</font></td>
</tr>
</tbody></table>
</li>
<li><p>特点：</p>
<ul>
<li>可以作为表达式嵌套在其他语句中使用，这时可以用在任何地方，begin end 中或 begin end外面。也可以作为独立的语句去使用，但只能放在begin end中使用。</li>
<li>如果 WHEN 中的值满足或条件成立，则执行对应的 THEN 后面的语句，并且结束 CASE；如果都不满足，则执行 ELSE 中的语句或值。</li>
<li>ELSE 可以省略，如果 ELSE 省略了，并且所有的 WHEN 条件都不满足，则返回 null。</li>
</ul>
</li>
<li><p>案例；创建存储过程，根据传入的成绩，来显示等级。（90——100 显示A，80——90 显示B，60——80 显示C，否则显示D）</p>
<ul>
<li><font color="#e96900">delimiter $<br>  create procedure test_case(in score int)<br>  begin<br>    case<br>    when score &gt;&#x3D; 90 then select &#39;A&#39;;<br>    when score &gt;&#x3D; 80 then select &#39;B&#39;;<br>    when score &gt;&#x3D; 60 then select &#39;C&#39;;<br>    else select &#39;D&#39;;<br>    end case;<br>  end $</font></li>
<li>调用：<font color="#e96900">call test_case(85);</font></li>
</ul>
</li>
</ul>
<p><strong><font color="#0000ee">3、if结构（实现多重分支）</font></strong></p>
<ul>
<li><font color="#e96900" size="4">if 条件1 then 语句1;<br>elseif 条件2 then 语句2;<br>……<br>[else 语句n;]<br>end if;</font></li>
<li>只能应用在begin end中，比如存储过程、函数</li>
<li>案例：根据传入的成绩，来返回等级。（90——100 返回，80——90 返回，60——80 返回，否则返回D）<ul>
<li><font color="#e96900">delimiter $<br>  create function test_if(score int) returns char<br>  begin<br>    if score &gt;&#x3D; 90 then return &#39;A&#39;;<br>    elseif score &gt;&#x3D; 80 then return &#39;B&#39;;<br>    elseif score &gt;&#x3D; 60 then return &#39;C&#39;;<br>    else return &#39;D&#39;;<br>    end if;<br>  end $</font></li>
<li>调用：<font color="#e96900">select test_if(85);</font></li>
</ul>
</li>
</ul>
</blockquote>
<h4 id="B、循环结构"><a href="#B、循环结构" class="headerlink" title="B、循环结构"></a>B、循环结构</h4><blockquote>
<ul>
<li><strong><font color="#0000ee">1、分类：</font></strong><ul>
<li><font color="#e96900">while</font></li>
<li><font color="#e96900">loop</font></li>
<li><font color="#e96900">repeat</font></li>
</ul>
</li>
<li><strong><font color="#0000ee">2、循环控制：</font></strong><ul>
<li><font color="#e96900">iterate</font>：类似于continue，结束本次循环，继续下一次</li>
<li><font color="#e96900">leave</font>：类似于brek，跳出，结束当前所在循环</li>
</ul>
</li>
<li><strong><font color="#0000ee">3、while 循环的语法：（类似于java中的while）</font></strong><ul>
<li><font color="#e96900" size="4">[标签:] while 循环条件 do<br>    循环体;<br>  end while [标签];</font></li>
</ul>
</li>
<li><strong><font color="#0000ee">4、loop 循环的语法：（没有条件的死循环）</font></strong><ul>
<li><font color="#e96900">[标签:] loop<br>    循环体<br>  end loop [标签];</font></li>
<li>可以用来模拟简单的死循环，搭配循环控制语句使用</li>
</ul>
</li>
<li><strong><font color="#0000ee">5、repeat 循环的语法：（类似java中的do while）</font></strong><ul>
<li><font color="#e96900">[标签:] repeat<br>    循环体;<br>  util 结束循环的条件<br>  end repeat [标签];</font></li>
</ul>
</li>
<li><strong><font color="#0000ee">6、案例演示：</font></strong><ul>
<li><strong>案例1（无循环控制语句）：批量插入，根据次数插入到admin表中多条记录</strong><ul>
<li><font color="#e96900">delimiter $<br>  create procedure test_while1(in insertCount int)<br>  begin<br>    declare i int default 1;<br>    while i&lt;&#x3D;insertCount do<br>      insert into admin(username, `password`)<br>    values(concat(&#39;Rose_&#39;, i), &#39;666&#39;);<br>      set i &#x3D; i+1;<br>    end while;<br>  end $</font></li>
<li>调用：<font color="#e96900">call test_while1(100);</font></li>
</ul>
</li>
<li><strong>案例2（带循环控制语句 leave）：批量插入，固定插入20条记录到admin表中</strong><ul>
<li><font color="#e96900">delimiter $<br>  create procedure test_while2()<br>  begin<br>    declare i int default 1;<br>    label_a: while true do<br>      insert into admin(username, `password`) values(concat(&#39;xiaohua_&#39;, i), &#39;000&#39;);<br>      if i&gt;&#x3D;20 then leave label_a; # 加了一条循环控制语句，必须带上标签<br>    end if;<br>      set i &#x3D; i+1;<br>    end while label_a;<br>  end $</font></li>
<li>调用：<font color="#e96900">call test_while2();</font></li>
</ul>
</li>
<li><strong>案例3（带循环控制语句 iterate）：批量插入，传入次数，只插入偶数次记录到admin表中</strong><ul>
<li><font color="#e96900">delimiter $<br>  create procedure test_while3(in insertCount int)<br>  begin<br>    declare i int default 1;<br>    label_b: while i&lt;&#x3D;insertCount do<br>      if i%2&#x3D;1 then<br>        set i &#x3D; i+1;<br>        iterate label_b; # 加了一条循环控制语句，必须带上标签<br>      else<br>          insert into admin(username, `password`) values(concat(&#39;yczlab_&#39;, i), &#39;000&#39;);<br>          set i &#x3D; i+1;<br>      end if;<br>    end while label_b;<br>  end $</font></li>
<li>调用：<font color="#e96900">call test_while3(100);</font></li>
</ul>
</li>
</ul>
</li>
</ul>
</blockquote>
<h4 id="C、经典案例"><a href="#C、经典案例" class="headerlink" title="C、经典案例"></a>C、经典案例</h4><blockquote>
<p>案例1：已知表 stringcontent(id int 自增长, content varchar(20))，向该表插入指定个数的随机字符串</p>
<ul>
<li><font color="#e96900">drop table if exists stringcontent;<br>create table stringcontent(<br>  id int PRIMARY KEY AUTO_INCREMENT,<br>  content varchar(20)<br>);</font></li>
<li><font color="#e96900">delimiter $<br>create procedure test_randstr_insert(in insertCount int)<br>begin<br>  declare str varchar(26) default &#39;abcdefghijklmnopqrstuvwxyz&#39;;<br>  declare startIndex int default 1;<br>  declare len int default 1;<br>  while insertCount&gt;&#x3D;1 do<br>    set startIndex &#x3D; floor(rand()*26 + 1); #随机产生[1,26]的整数<br>    set len &#x3D; floor(rand()*(26-startIndex+1)+1); #随机产生[1, 26-startIndex+1]的整数<br>    set len &#x3D; if(len&gt;20, 20, len); #保证长度最多为20<br>    insert into stringcontent(content) values(substr(str, startIndex, len));<br>    set insertCount &#x3D; insertCount-1;<br>  end while;<br>end $</font></li>
<li><font color="#e96900">call test_randstr_insert(100);</font></li>
</ul>
</blockquote>

                
            </div>
            <hr/>

            

    <div class="reprint" id="reprint-statement">
        
            <div class="reprint__author">
                <span class="reprint-meta" style="font-weight: bold;">
                    <i class="fas fa-user">
                        文章作者:
                    </i>
                </span>
                <span class="reprint-info">
                    <a href="/about" rel="external nofollow noreferrer">YangChongZhi</a>
                </span>
            </div>
            <div class="reprint__type">
                <span class="reprint-meta" style="font-weight: bold;">
                    <i class="fas fa-link">
                        文章链接:
                    </i>
                </span>
                <span class="reprint-info">
                    <a href="http://yczlab.top/posts/b6041c1e.html">http://yczlab.top/posts/b6041c1e.html</a>
                </span>
            </div>
            <div class="reprint__notice">
                <span class="reprint-meta" style="font-weight: bold;">
                    <i class="fas fa-copyright">
                        版权声明:
                    </i>
                </span>
                <span class="reprint-info">
                    本博客所有文章除特別声明外，均采用
                    <a href="https://creativecommons.org/licenses/by/4.0/deed.zh" rel="external nofollow noreferrer" target="_blank">CC BY 4.0</a>
                    许可协议。转载请注明来源
                    <a href="/about" target="_blank">YangChongZhi</a>
                    !
                </span>
            </div>
        
    </div>

    <script async defer>
      document.addEventListener("copy", function (e) {
        let toastHTML = '<span>复制成功，请遵循本文的转载规则</span><button class="btn-flat toast-action" onclick="navToReprintStatement()" style="font-size: smaller">查看</a>';
        M.toast({html: toastHTML})
      });

      function navToReprintStatement() {
        $("html, body").animate({scrollTop: $("#reprint-statement").offset().top - 80}, 800);
      }
    </script>



            <div class="tag_share" style="display: block;">
                <div class="post-meta__tag-list" style="display: inline-block;">
                    
                        <div class="article-tag">
                            
                                <a href="/tags/MySql/">
                                    <span class="chip bg-color">MySql</span>
                                </a>
                            
                        </div>
                    
                </div>
                <div class="post_share" style="zoom: 80%; width: fit-content; display: inline-block; float: right; margin: -0.15rem 0;">
                    <link rel="stylesheet" type="text/css" href="/libs/share/css/share.min.css">
<div id="article-share">

    
    <div class="social-share" data-sites="twitter,facebook,google,qq,qzone,wechat,weibo,douban,linkedin" data-wechat-qrcode-helper="<p>微信扫一扫即可分享！</p>"></div>
    <script src="/libs/share/js/social-share.min.js"></script>
    

    

</div>

                </div>
            </div>
            
                <style>
    #reward {
        margin: 40px 0;
        text-align: center;
    }

    #reward .reward-link {
        font-size: 1.4rem;
        line-height: 38px;
    }

    #reward .btn-floating:hover {
        box-shadow: 0 6px 12px rgba(0, 0, 0, 0.2), 0 5px 15px rgba(0, 0, 0, 0.2);
    }

    #rewardModal {
        width: 320px;
        height: 350px;
    }

    #rewardModal .reward-title {
        margin: 15px auto;
        padding-bottom: 5px;
    }

    #rewardModal .modal-content {
        padding: 10px;
    }

    #rewardModal .close {
        position: absolute;
        right: 15px;
        top: 15px;
        color: rgba(0, 0, 0, 0.5);
        font-size: 1.3rem;
        line-height: 20px;
        cursor: pointer;
    }

    #rewardModal .close:hover {
        color: #ef5350;
        transform: scale(1.3);
        -moz-transform:scale(1.3);
        -webkit-transform:scale(1.3);
        -o-transform:scale(1.3);
    }

    #rewardModal .reward-tabs {
        margin: 0 auto;
        width: 210px;
    }

    .reward-tabs .tabs {
        height: 38px;
        margin: 10px auto;
        padding-left: 0;
    }

    .reward-content ul {
        padding-left: 0 !important;
    }

    .reward-tabs .tabs .tab {
        height: 38px;
        line-height: 38px;
    }

    .reward-tabs .tab a {
        color: #fff;
        background-color: #ccc;
    }

    .reward-tabs .tab a:hover {
        background-color: #ccc;
        color: #fff;
    }

    .reward-tabs .wechat-tab .active {
        color: #fff !important;
        background-color: #22AB38 !important;
    }

    .reward-tabs .alipay-tab .active {
        color: #fff !important;
        background-color: #019FE8 !important;
    }

    .reward-tabs .reward-img {
        width: 210px;
        height: 210px;
    }
</style>

<div id="reward">
    <a href="#rewardModal" class="reward-link modal-trigger btn-floating btn-medium waves-effect waves-light red">赏</a>

    <!-- Modal Structure -->
    <div id="rewardModal" class="modal">
        <div class="modal-content">
            <a class="close modal-close"><i class="fas fa-times"></i></a>
            <h4 class="reward-title">你的赏识是我前进的动力</h4>
            <div class="reward-content">
                <div class="reward-tabs">
                    <ul class="tabs row">
                        <li class="tab col s6 alipay-tab waves-effect waves-light"><a href="#alipay">支付宝</a></li>
                        <li class="tab col s6 wechat-tab waves-effect waves-light"><a href="#wechat">微 信</a></li>
                    </ul>
                    <div id="alipay">
                        <img src="/medias/reward/alipay.jpg" class="reward-img" alt="支付宝打赏二维码">
                    </div>
                    <div id="wechat">
                        <img src="/medias/reward/wechat.png" class="reward-img" alt="微信打赏二维码">
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<script>
    $(function () {
        $('.tabs').tabs();
    });
</script>

            
        </div>
    </div>

    

    

    

    

    
        <style>
    .valine-card {
        margin: 1.5rem auto;
    }

    .valine-card .card-content {
        padding: 20px 20px 5px 20px;
    }

    #vcomments textarea {
        box-sizing: border-box;
        background: url("/medias/comment_bg.webp") 100% 100% no-repeat;
    }

    #vcomments p {
        margin: 2px 2px 10px;
        font-size: 1.05rem;
        line-height: 1.78rem;
    }

    #vcomments blockquote p {
        text-indent: 0.2rem;
    }

    #vcomments a {
        padding: 0 2px;
        color: #4cbf30;
        font-weight: 500;
        text-decoration: none;
    }

    #vcomments img {
        max-width: 100%;
        height: auto;
        cursor: pointer;
    }

    #vcomments ol li {
        list-style-type: decimal;
    }

    #vcomments ol,
    ul {
        display: block;
        padding-left: 2em;
        word-spacing: 0.05rem;
    }

    #vcomments ul li,
    ol li {
        display: list-item;
        line-height: 1.8rem;
        font-size: 1rem;
    }

    #vcomments ul li {
        list-style-type: disc;
    }

    #vcomments ul ul li {
        list-style-type: circle;
    }

    #vcomments table, th, td {
        padding: 12px 13px;
        border: 1px solid #dfe2e5;
    }

    #vcomments table, th, td {
        border: 0;
    }

    table tr:nth-child(2n), thead {
        background-color: #fafafa;
    }

    #vcomments table th {
        background-color: #f2f2f2;
        min-width: 80px;
    }

    #vcomments table td {
        min-width: 80px;
    }

    #vcomments h1 {
        font-size: 1.85rem;
        font-weight: bold;
        line-height: 2.2rem;
    }

    #vcomments h2 {
        font-size: 1.65rem;
        font-weight: bold;
        line-height: 1.9rem;
    }

    #vcomments h3 {
        font-size: 1.45rem;
        font-weight: bold;
        line-height: 1.7rem;
    }

    #vcomments h4 {
        font-size: 1.25rem;
        font-weight: bold;
        line-height: 1.5rem;
    }

    #vcomments h5 {
        font-size: 1.1rem;
        font-weight: bold;
        line-height: 1.4rem;
    }

    #vcomments h6 {
        font-size: 1rem;
        line-height: 1.3rem;
    }

    #vcomments p {
        font-size: 1rem;
        line-height: 1.5rem;
    }

    #vcomments hr {
        margin: 12px 0;
        border: 0;
        border-top: 1px solid #ccc;
    }

    #vcomments blockquote {
        margin: 15px 0;
        border-left: 5px solid #42b983;
        padding: 1rem 0.8rem 0.3rem 0.8rem;
        color: #666;
        background-color: rgba(66, 185, 131, .1);
    }

    #vcomments pre {
        font-family: monospace, monospace;
        padding: 1.2em;
        margin: .5em 0;
        background: #272822;
        overflow: auto;
        border-radius: 0.3em;
        tab-size: 4;
    }

    #vcomments code {
        font-family: monospace, monospace;
        padding: 1px 3px;
        font-size: 0.92rem;
        color: #e96900;
        background-color: #f8f8f8;
        border-radius: 2px;
    }

    #vcomments pre code {
        font-family: monospace, monospace;
        padding: 0;
        color: #e8eaf6;
        background-color: #272822;
    }

    #vcomments pre[class*="language-"] {
        padding: 1.2em;
        margin: .5em 0;
    }

    #vcomments code[class*="language-"],
    pre[class*="language-"] {
        color: #e8eaf6;
    }

    #vcomments [type="checkbox"]:not(:checked), [type="checkbox"]:checked {
        position: inherit;
        margin-left: -1.3rem;
        margin-right: 0.4rem;
        margin-top: -1px;
        vertical-align: middle;
        left: unset;
        visibility: visible;
    }

    #vcomments b,
    strong {
        font-weight: bold;
    }

    #vcomments dfn {
        font-style: italic;
    }

    #vcomments small {
        font-size: 85%;
    }

    #vcomments cite {
        font-style: normal;
    }

    #vcomments mark {
        background-color: #fcf8e3;
        padding: .2em;
    }

    #vcomments table, th, td {
        padding: 12px 13px;
        border: 1px solid #dfe2e5;
    }

    table tr:nth-child(2n), thead {
        background-color: #fafafa;
    }

    #vcomments table th {
        background-color: #f2f2f2;
        min-width: 80px;
    }

    #vcomments table td {
        min-width: 80px;
    }

    #vcomments [type="checkbox"]:not(:checked), [type="checkbox"]:checked {
        position: inherit;
        margin-left: -1.3rem;
        margin-right: 0.4rem;
        margin-top: -1px;
        vertical-align: middle;
        left: unset;
        visibility: visible;
    }
</style>

<div class="card valine-card" data-aos="fade-up">
    <div class="comment_headling" style="font-size: 20px; font-weight: 700; position: relative; padding-left: 20px; top: 15px; padding-bottom: 5px;">
        <i class="fas fa-comments fa-fw" aria-hidden="true"></i>
        <span>评论</span>
    </div>
    <div id="vcomments" class="card-content" style="display: grid">
    </div>
</div>

<script src="/libs/valine/av-min.js"></script>
<script src="/libs/valine/Valine.min.js"></script>
<script>
    new Valine({
        el: '#vcomments',
        appId: 'jJDtz1MXtl9cRxLcrXYvlvhd-9Nh9j0Va',
        appKey: 'UpF6BuVYYhInv6M8vXS0dWRt',
        pageSize: '10',
        notify: 'false' === 'true',
        verify: 'false' === 'true',
        visitor: 'false' === 'true',
        avatar: 'monsterid',
		recordIP: 'true',
		enableQQ: 'true',
		requiredFields: ["nick", "mail"],
        lang: 'zh-cn',
        placeholder: '请开始你的表演吧！\n注意博客留言要求填写昵称、邮箱'
    });
</script>

    

    

    

    

<article id="prenext-posts" class="prev-next articles">
    <div class="row article-row">
        
        <div class="article col s12 m6" data-aos="fade-up">
            <div class="article-badge left-badge text-color">
                <i class="fas fa-chevron-left"></i>&nbsp;上一篇</div>
            <div class="card">
                <a href="/posts/791ea0e2.html">
                    <div class="card-image">
                        
                        
                        <img src="/medias/featureimages/3.jpg" class="responsive-img" alt="IntelliJ IDEA快捷键大全">
                        
                        <span class="card-title">IntelliJ IDEA快捷键大全</span>
                    </div>
                </a>
                <div class="card-content article-content">
                    <div class="summary block-with-text">
                        
                              
引言：
本文参考了 IntelliJ IDEA 的官网，列举了IntelliJ IDEA（Windows 版）的所有快捷键。并在此基础上，为 90% 以上的快捷键提供了动图演示，能够直观的看到操作效果。该快捷键共分 16 种，可以方便
                        
                    </div>
                    <div class="publish-info">
                        <span class="publish-date">
                            <i class="far fa-clock fa-fw icon-date"></i>2022-05-18
                        </span>
                        <span class="publish-author">
                            
                            <i class="fas fa-bookmark fa-fw icon-category"></i>
                            
                            <a href="/categories/Java/" class="post-category">
                                    Java
                                </a>
                            
                            
                        </span>
                    </div>
                </div>
                
                <div class="card-action article-tags">
                    
                    <a href="/tags/Java/">
                        <span class="chip bg-color">Java</span>
                    </a>
                    
                </div>
                
            </div>
        </div>
        
        
        <div class="article col s12 m6" data-aos="fade-up">
            <div class="article-badge right-badge text-color">
                下一篇&nbsp;<i class="fas fa-chevron-right"></i>
            </div>
            <div class="card">
                <a href="/posts/ed3b1c3a.html">
                    <div class="card-image">
                        
                        
                        <img src="/medias/featureimages/18.jpg" class="responsive-img" alt="Redis常用命令">
                        
                        <span class="card-title">Redis常用命令</span>
                    </div>
                </a>
                <div class="card-content article-content">
                    <div class="summary block-with-text">
                        
                              
引言：
Remote Dictionary Server（Redis）通常被称为结构服务器，因为值（value）可以是字符串（String）、哈希（Hash）、列表（List）、集合（Set）和有序集合（Sorted Set）等类型。
                        
                    </div>
                    <div class="publish-info">
                            <span class="publish-date">
                                <i class="far fa-clock fa-fw icon-date"></i>2021-09-26
                            </span>
                        <span class="publish-author">
                            
                            <i class="fas fa-bookmark fa-fw icon-category"></i>
                            
                            <a href="/categories/Redis/" class="post-category">
                                    Redis
                                </a>
                            
                            
                        </span>
                    </div>
                </div>
                
                <div class="card-action article-tags">
                    
                    <a href="/tags/Java/">
                        <span class="chip bg-color">Java</span>
                    </a>
                    
                    <a href="/tags/Redis/">
                        <span class="chip bg-color">Redis</span>
                    </a>
                    
                </div>
                
            </div>
        </div>
        
    </div>
</article>

</div>



<!-- 代码块功能依赖 -->
<script type="text/javascript" src="/libs/codeBlock/codeBlockFuction.js"></script>

<!-- 代码语言 -->

<script type="text/javascript" src="/libs/codeBlock/codeLang.js"></script>


<!-- 代码块复制 -->

<script type="text/javascript" src="/libs/codeBlock/codeCopy.js"></script>


<!-- 代码块收缩 -->

<script type="text/javascript" src="/libs/codeBlock/codeShrink.js"></script>


    </div>
    <div id="toc-aside" class="expanded col l3 hide-on-med-and-down">
        <div class="toc-widget card" style="background-color: white;">
            <div class="toc-title"><i class="far fa-list-alt"></i>&nbsp;&nbsp;目录</div>
            <div id="toc-content"></div>
        </div>
    </div>
</div>

<!-- TOC 悬浮按钮. -->

<div id="floating-toc-btn" class="hide-on-med-and-down">
    <a class="btn-floating btn-large bg-color">
        <i class="fas fa-list-ul"></i>
    </a>
</div>


<script src="/libs/tocbot/tocbot.min.js"></script>
<script>
    $(function () {
        tocbot.init({
            tocSelector: '#toc-content',
            contentSelector: '#articleContent',
            headingsOffset: -($(window).height() * 0.4 - 45),
            collapseDepth: Number('0'),
            headingSelector: 'h2, h3, h4'
        });

        // modify the toc link href to support Chinese.
        let i = 0;
        let tocHeading = 'toc-heading-';
        $('#toc-content a').each(function () {
            $(this).attr('href', '#' + tocHeading + (++i));
        });

        // modify the heading title id to support Chinese.
        i = 0;
        $('#articleContent').children('h2, h3, h4').each(function () {
            $(this).attr('id', tocHeading + (++i));
        });

        // Set scroll toc fixed.
        let tocHeight = parseInt($(window).height() * 0.4 - 64);
        let $tocWidget = $('.toc-widget');
        $(window).scroll(function () {
            let scroll = $(window).scrollTop();
            /* add post toc fixed. */
            if (scroll > tocHeight) {
                $tocWidget.addClass('toc-fixed');
            } else {
                $tocWidget.removeClass('toc-fixed');
            }
        });

        
        /* 修复文章卡片 div 的宽度. */
        let fixPostCardWidth = function (srcId, targetId) {
            let srcDiv = $('#' + srcId);
            if (srcDiv.length === 0) {
                return;
            }

            let w = srcDiv.width();
            if (w >= 450) {
                w = w + 21;
            } else if (w >= 350 && w < 450) {
                w = w + 18;
            } else if (w >= 300 && w < 350) {
                w = w + 16;
            } else {
                w = w + 14;
            }
            $('#' + targetId).width(w);
        };

        // 切换TOC目录展开收缩的相关操作.
        const expandedClass = 'expanded';
        let $tocAside = $('#toc-aside');
        let $mainContent = $('#main-content');
        $('#floating-toc-btn .btn-floating').click(function () {
            if ($tocAside.hasClass(expandedClass)) {
                $tocAside.removeClass(expandedClass).hide();
                $mainContent.removeClass('l9');
            } else {
                $tocAside.addClass(expandedClass).show();
                $mainContent.addClass('l9');
            }
            fixPostCardWidth('artDetail', 'prenext-posts');
        });
        
    });
</script>

    

</main>




    <footer class="page-footer bg-color">
    
        <link rel="stylesheet" href="/libs/aplayer/APlayer.min.css">
<style>
    .aplayer .aplayer-lrc p {
        
        display: none;
        
        font-size: 12px;
        font-weight: 700;
        line-height: 16px !important;
    }

    .aplayer .aplayer-lrc p.aplayer-lrc-current {
        
        display: none;
        
        font-size: 15px;
        color: #42b983;
    }

    
    .aplayer.aplayer-fixed.aplayer-narrow .aplayer-body {
        left: -66px !important;
    }

    .aplayer.aplayer-fixed.aplayer-narrow .aplayer-body:hover {
        left: 0px !important;
    }

    
</style>
<div class="">
    
    <div class="row">
        <meting-js class="col l8 offset-l2 m10 offset-m1 s12"
                   server="netease"
                   type="playlist"
                   id="7565528433"
                   fixed='true'
                   autoplay='false'
                   theme='#42b983'
                   loop='all'
                   order='random'
                   preload='auto'
                   volume='0.4'
                   list-folded='true'
        >
        </meting-js>
    </div>
</div>

<script src="/libs/aplayer/APlayer.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/meting@2/dist/Meting.min.js"></script>

    
    <div class="container row center-align" style="margin-bottom: 15px !important;">
        <div class="col s12 m8 l8 copy-right">
            Copyright&nbsp;&copy;
            
                <span id="year">2019-2024</span>
            
            <span id="year">2019</span>
            <a href="/about" target="_blank">YangChongZhi</a>
            |&nbsp;Powered by&nbsp;<a href="https://hexo.io/" target="_blank">Hexo</a>
            |&nbsp;Theme&nbsp;<a href="https://github.com/blinkfox/hexo-theme-matery" target="_blank">Matery</a>
            <br>
            
            &nbsp;<i class="fas fa-chart-area"></i>&nbsp;站点总字数:&nbsp;<span
                class="white-color">236.5k</span>&nbsp;字
            
            
            
            
            
            
            <span id="busuanzi_container_site_pv">
                |&nbsp;<i class="far fa-eye"></i>&nbsp;总访问量:&nbsp;<span id="busuanzi_value_site_pv"
                    class="white-color"></span>&nbsp;次
            </span>
            
            
            <span id="busuanzi_container_site_uv">
                |&nbsp;<i class="fas fa-users"></i>&nbsp;总访问人数:&nbsp;<span id="busuanzi_value_site_uv"
                    class="white-color"></span>&nbsp;人
            </span>
            
            <br>
            
            <span id="sitetime">载入运行时间...</span>
            <script>
                function siteTime() {
                    var seconds = 1000;
                    var minutes = seconds * 60;
                    var hours = minutes * 60;
                    var days = hours * 24;
                    var years = days * 365;
                    var today = new Date();
                    var startYear = "2019";
                    var startMonth = "6";
                    var startDate = "28";
                    var startHour = "0";
                    var startMinute = "0";
                    var startSecond = "0";
                    var todayYear = today.getFullYear();
                    var todayMonth = today.getMonth() + 1;
                    var todayDate = today.getDate();
                    var todayHour = today.getHours();
                    var todayMinute = today.getMinutes();
                    var todaySecond = today.getSeconds();
                    var t1 = Date.UTC(startYear, startMonth, startDate, startHour, startMinute, startSecond);
                    var t2 = Date.UTC(todayYear, todayMonth, todayDate, todayHour, todayMinute, todaySecond);
                    var diff = t2 - t1;
                    var diffYears = Math.floor(diff / years);
                    var diffDays = Math.floor((diff / days) - diffYears * 365);
                    var diffHours = Math.floor((diff - (diffYears * 365 + diffDays) * days) / hours);
                    var diffMinutes = Math.floor((diff - (diffYears * 365 + diffDays) * days - diffHours * hours) /
                        minutes);
                    var diffSeconds = Math.floor((diff - (diffYears * 365 + diffDays) * days - diffHours * hours -
                        diffMinutes * minutes) / seconds);
                    if (startYear == todayYear) {
                        document.getElementById("year").innerHTML = todayYear;
                        document.getElementById("sitetime").innerHTML = "本站已安全运行 " + diffDays + " 天 " + diffHours +
                            " 小时 " + diffMinutes + " 分钟 " + diffSeconds + " 秒";
                    } else {
                        document.getElementById("year").innerHTML = startYear + " - " + todayYear;
                        document.getElementById("sitetime").innerHTML = "本站已安全运行 " + diffYears + " 年 " + diffDays +
                            " 天 " + diffHours + " 小时 " + diffMinutes + " 分钟 " + diffSeconds + " 秒";
                    }
                }
                setInterval(siteTime, 1000);
            </script>
            
            <br>
            
            <span id="icp"><img src="/medias/icp.png" style="vertical-align: text-bottom;" />
                <a href="http://beian.miit.gov.cn/" target="_blank">渝ICP备2021001798号-1</a>
            </span>
            
        </div>
        <div class="col s12 m4 l4 social-link social-statis">
    <a href="https://github.com/yczlab" class="tooltipped" target="_blank" data-tooltip="访问我的GitHub" data-position="top" data-delay="50">
        <i class="fab fa-github"></i>
    </a>



    <a href="https://gitee.com/yczlab" class="tooltipped" target="_blank" data-tooltip="访问我的码云" data-position="top" data-delay="50">
        <i class="fab fa-github"></i>
    </a>



    <a href="mailto:2685733832@qq.com" class="tooltipped" target="_blank" data-tooltip="邮件联系我" data-position="top" data-delay="50">
        <i class="fas fa-envelope-open"></i>
    </a>







    <a href="tencent://AddContact/?fromId=50&fromSubId=1&subcmd=all&uin=2685733832" class="tooltipped" target="_blank" data-tooltip="QQ联系我: 2685733832" data-position="top" data-delay="50">
        <i class="fab fa-qq"></i>
    </a>



    <a href="tencent://AddContact/?fromId=50&fromSubId=1&subcmd=all&uin=2685733832" class="tooltipped" target="_blank" data-tooltip="微信联系我: yczlab" data-position="top" data-delay="50">
        <i class="fab fa-weixin"></i>
    </a>



    <a href="https://weibo.com/yczlab" class="tooltipped" target="_blank" data-tooltip="关注我的微博: https://weibo.com/yczlab" data-position="top" data-delay="50">
        <i class="fab fa-weibo"></i>
    </a>



    <a href="https://www.zhihu.com/people/yczlab" class="tooltipped" target="_blank" data-tooltip="关注我的知乎: https://www.zhihu.com/people/yczlab" data-position="top" data-delay="50">
        <i class="fab fa-zhihu1">知</i>
    </a>



</div>
    </div>
</footer>

<div class="progress-bar"></div>


    <!-- 搜索遮罩框 -->
<div id="searchModal" class="modal">
    <div class="modal-content">
        <div class="search-header">
            <span class="title"><i class="fas fa-search"></i>&nbsp;&nbsp;搜索</span>
            <input type="search" id="searchInput" name="s" placeholder="请输入搜索的关键字"
                   class="search-input">
        </div>
        <div id="searchResult"></div>
    </div>
</div>

<script type="text/javascript">
$(function () {
    var searchFunc = function (path, search_id, content_id) {
        'use strict';
        $.ajax({
            url: path,
            dataType: "xml",
            success: function (xmlResponse) {
                // get the contents from search data
                var datas = $("entry", xmlResponse).map(function () {
                    return {
                        title: $("title", this).text(),
                        content: $("content", this).text(),
                        url: $("url", this).text()
                    };
                }).get();
                var $input = document.getElementById(search_id);
                var $resultContent = document.getElementById(content_id);
                $input.addEventListener('input', function () {
                    var str = '<ul class=\"search-result-list\">';
                    var keywords = this.value.trim().toLowerCase().split(/[\s\-]+/);
                    $resultContent.innerHTML = "";
                    if (this.value.trim().length <= 0) {
                        return;
                    }
                    // perform local searching
                    datas.forEach(function (data) {
                        var isMatch = true;
                        var data_title = data.title.trim().toLowerCase();
                        var data_content = data.content.trim().replace(/<[^>]+>/g, "").toLowerCase();
                        var data_url = data.url;
                        data_url = data_url.indexOf('/') === 0 ? data.url : '/' + data_url;
                        var index_title = -1;
                        var index_content = -1;
                        var first_occur = -1;
                        // only match artiles with not empty titles and contents
                        if (data_title !== '' && data_content !== '') {
                            keywords.forEach(function (keyword, i) {
                                index_title = data_title.indexOf(keyword);
                                index_content = data_content.indexOf(keyword);
                                if (index_title < 0 && index_content < 0) {
                                    isMatch = false;
                                } else {
                                    if (index_content < 0) {
                                        index_content = 0;
                                    }
                                    if (i === 0) {
                                        first_occur = index_content;
                                    }
                                }
                            });
                        }
                        // show search results
                        if (isMatch) {
                            str += "<li><a href='" + data_url + "' class='search-result-title'>" + data_title + "</a>";
                            var content = data.content.trim().replace(/<[^>]+>/g, "");
                            if (first_occur >= 0) {
                                // cut out 100 characters
                                var start = first_occur - 20;
                                var end = first_occur + 80;
                                if (start < 0) {
                                    start = 0;
                                }
                                if (start === 0) {
                                    end = 100;
                                }
                                if (end > content.length) {
                                    end = content.length;
                                }
                                var match_content = content.substr(start, end);
                                // highlight all keywords
                                keywords.forEach(function (keyword) {
                                    var regS = new RegExp(keyword, "gi");
                                    match_content = match_content.replace(regS, "<em class=\"search-keyword\">" + keyword + "</em>");
                                });

                                str += "<p class=\"search-result\">" + match_content + "...</p>"
                            }
                            str += "</li>";
                        }
                    });
                    str += "</ul>";
                    $resultContent.innerHTML = str;
                });
            }
        });
    };

    searchFunc('/search.xml', 'searchInput', 'searchResult');
});
</script>

    <!-- 回到顶部按钮 -->
<div id="backTop" class="top-scroll">
    <a class="btn-floating btn-large waves-effect waves-light" href="#!">
        <i class="fas fa-arrow-up"></i>
    </a>
</div>


    <script src="/libs/materialize/materialize.min.js"></script>
    <script src="/libs/masonry/masonry.pkgd.min.js"></script>
    <script src="/libs/aos/aos.js"></script>
    <script src="/libs/scrollprogress/scrollProgress.min.js"></script>
    <script src="/libs/lightGallery/js/lightgallery-all.min.js"></script>
    <script src="/js/matery.js"></script>

    <!-- Baidu Analytics -->

    <!-- Baidu Push -->

<script>
    (function () {
        var bp = document.createElement('script');
        var curProtocol = window.location.protocol.split(':')[0];
        if (curProtocol === 'https') {
            bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
        } else {
            bp.src = 'http://push.zhanzhang.baidu.com/push.js';
        }
        var s = document.getElementsByTagName("script")[0];
        s.parentNode.insertBefore(bp, s);
    })();
</script>

    
    <script src="/libs/others/clicklove.js" async="async"></script>
    
    
    <script async src="/libs/others/busuanzi.pure.mini.js"></script>
    

    
        <script src="//code.tidio.co/ef3vil8uaqrvp7giqeg545xldzmymqss.js"></script>
    

    

	
    
    <script type="text/javascript" color="0,0,255"
        pointColor="0,0,255" opacity='0.5'
        zIndex="-1" count="99"
        src="/libs/background/canvas-nest.js"></script>
    

    
    
    <script type="text/javascript" size="150" alpha='0.6'
        zIndex="-1" src="/libs/background/ribbon-refresh.min.js" async="async"></script>
    

    
    <script type="text/javascript" src="/libs/background/ribbon-dynamic.js" async="async"></script>
    

    
    <script src="/libs/instantpage/instantpage.js" type="module"></script>
    
	
	<script type="text/javascript">
	var OriginTitile = document.title,st;
	document.addEventListener("visibilitychange", function () {
		document.hidden ? (document.title = "Σ(っ °Д °;)っ我隐藏了！", clearTimeout(st)) : (document.title="(๑•̀ㅂ•́) ✧被发现了！", st=setTimeout(function () {document.title = OriginTitile}, 3e3))
	});
	</script>
	
	<!-- 背景樱花飘落特效 -->
	
	
	<!-- 背景雪花飘落特效 -->
	
	
	<!-- 数字雨特效 -->
	
		<script type="text/javascript">
		//只在桌面版网页启用特效
		var windowWidth = $(window).width();
		if (windowWidth > 768) {
			document.write('<canvas id="digitalrain" width="1440" height="900" style="position:fixed; z-index:-2; right:0px; bottom:0px; min-width:100%; min-height:100%; height:auto; width:auto;"><\/canvas>');
			document.write('<script type="text/javascript" src="/js/digitalrain.js"><\/script>');
		}
		</script>
	

</body>

</html>
